📌  相关文章
📜  选择数组元素的最低成本

📅  最后修改于: 2021-04-27 19:04:09             🧑  作者: Mango

给定一个由N个整数和整数M组成的数组arr [] ,并且在任意一天(例如d )选择任何数组元素(例如x )的成本为x * d 。任务是最大程度地减少选择1,2,3,…,N个阵列的成本,其中每天最多可以选择M个元素。

例子:

方法:想法是使用前缀求和数组。

  1. 将给定数组按升序排序。
  2. 将排序数组的前缀和存储在pref []中。当允许每天最多选择一个元素时该前缀和给出选择1,2,3,…N个数组元素的最小开销。
  3. 要查找每天最多允许M个元素选择时的最低成本,请将前缀数组pref []从索引M更新为N
    pref[i] = pref[i] + pref[i-M]
    

    例如:

    arr[] = {6, 9, 3, 4, 4, 2, 6, 7, 8}
    After sorting arr[]:
    arr[] = {2, 3, 4, 4, 6, 6, 7, 8, 9}
    
    Prefix array is:
    pref[] = {2, 5, 9, 13, 19, 25, 32, 40, 49}
    Now at every index i, pref[i] gives the cost 
    of selecting i array element when atmost one 
    element is allowed to select each day.
    
    Now for M = 3, when at most 3 elements
    are allowed to select each day, then 
    by update every index(from M to N)
    of pref[] as:
    pref[i] = pref[i] + pref[i-M] 
    
    the cost of selecting elements 
    from (i-M+1)th to ith index on day 1,
    the cost of selecting elements 
    from (i-M)th to (i-2*M)th index on day 2
    ...
    ...
    ...
    the cost of selecting elements 
    from (i-n*M)th to 0th index on day N.
    
  4. 完成上述步骤后,当每天最多允许M个元素进行选择时,前缀数组pref []的每个索引(例如i )都会存储选择i个元素的成本。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
// Function that find the minimum cost of 
// selecting array element
void minimumCost(int arr[], int N, int M) {
      
    // Sorting the given array in 
    // increasing order
    sort(arr, arr + N);
      
    // To store the prefix sum of arr[] 
    int pref[N];
      
    pref[0] = arr[0];
      
    for(int i = 1; i < N; i++) {
        pref[i] = arr[i] + pref[i-1];
    }
      
    // Update the pref[] to find the cost
    // selecting array element by selecting
    // at most M element
    for(int i = M; i < N; i++) {
        pref[i] += pref[i-M];
    }
      
    // Print the pref[] for the result
    for(int i = 0; i < N; i++) {
        cout << pref[i] << ' ';
    }
      
}
  
// Driver Code
int main()
{
    int arr[] = {6, 19, 3, 4, 4, 2, 6, 7, 8};
    int M = 2;
    int N = sizeof(arr)/sizeof(arr[0]);
      
    minimumCost(arr, N, M);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
  
class GFG{
  
// Function that find the minimum cost of 
// selecting array element
static void minimumCost(int arr[], int N, int M) 
{
      
    // Sorting the given array in 
    // increasing order
    Arrays.sort(arr);
      
    // To store the prefix sum of arr[] 
    int []pref = new int[N];
    pref[0] = arr[0];
      
    for(int i = 1; i < N; i++)
    {
        pref[i] = arr[i] + pref[i - 1];
    }
      
    // Update the pref[] to find the cost
    // selecting array element by selecting
    // at most M element
    for(int i = M; i < N; i++)
    {
        pref[i] += pref[i - M];
    }
      
    // Print the pref[] for the result
    for(int i = 0; i < N; i++) 
    {
        System.out.print(pref[i] + " ");
    }
}
  
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 6, 19, 3, 4, 4, 2, 6, 7, 8 };
    int M = 2;
    int N = arr.length;
      
    minimumCost(arr, N, M);
}
}
  
// This code is contributed by sapnasingh4991


Python3
# Python3 program for the above approach 
  
# Function that find the minimum cost 
# of selecting array element 
def minimumCost(arr, N, M):
      
    # Sorting the given array in 
    # increasing order 
    arr.sort()
      
    # To store the prefix sum of arr[] 
    pref = []
      
    pref.append(arr[0])
      
    for i in range(1, N):
        pref.append(arr[i] + pref[i - 1])
      
    # Update the pref[] to find the cost 
    # selecting array element by selecting 
    # at most M element 
    for i in range(M, N):
        pref[i] += pref[i - M]
      
    # Print the pref[] for the result 
    for i in range(N):
        print(pref[i], end = ' ')
  
# Driver Code 
arr = [ 6, 19, 3, 4, 4, 2, 6, 7, 8 ]
M = 2
N = len(arr)
  
minimumCost(arr, N, M);
  
# This code is contributed by yatinagg


C#
// C# program for the above approach
using System;
  
class GFG{
  
// Function that find the minimum cost  
// of selecting array element
static void minimumCost(int []arr, int N,
                                   int M) 
{
      
    // Sorting the given array  
    // in increasing order
    Array.Sort(arr);
      
    // To store the prefix sum of []arr 
    int []pref = new int[N];
    pref[0] = arr[0];
      
    for(int i = 1; i < N; i++)
    {
       pref[i] = arr[i] + pref[i - 1];
    }
      
    // Update the pref[] to find the cost
    // selecting array element by selecting
    // at most M element
    for(int i = M; i < N; i++)
    {
       pref[i] += pref[i - M];
    }
      
    // Print the pref[] for the result
    for(int i = 0; i < N; i++) 
    {
       Console.Write(pref[i] + " ");
    }
}
  
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 6, 19, 3, 4, 4,  
                  2, 6, 7, 8 };
    int M = 2;
    int N = arr.Length;
      
    minimumCost(arr, N, M);
}
}
  
// This code is contributed by Amit Katiyar


输出:
2 5 11 18 30 43 62 83 121

时间复杂度: O(N * log N),其中N是数组中元素的数量。