📌  相关文章
📜  最小化使所有数组元素相等所需的插入和删除成本

📅  最后修改于: 2021-05-14 09:02:12             🧑  作者: Mango

给定大小为N (1≤N≤10 5 )的排序数组arr []以及两个整数A和B,任务是计算使所有数组元素递增或递减相等所需的最小成本。每次增加和减少的成本分别为AB。

例子:

方法:执行以下步骤:

  • 以升序对数组进行排序。
  • 遍历数组。
  • 初始化新数组以存储累积前缀和。
  • 如果AB都相等,则中间元素的成本最低。
  • 如果A小于B ,则通过将low设置为mid = 1 ,最小成本元素出现在mid的右侧。使用二进制搜索技术搜索该元素。
  • 如果A大于B ,则最小成本元素出现在mid的左侧。通过设置high = mid – 1 ,使用二进制搜索技术搜索该元素。

下面是上述方法的实现。

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to find minimum cost
// required to make all array elements equal
long long minCost(int arr[], int A,
                  int B, int N)
{
 
    // Sort the array
    sort(arr, arr + N);
 
    // Stores the prefix sum and sum
    // of the array respectively
    long long cumarr[N], sum = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        // Update sum
        sum += arr[i];
 
        // Update prefix sum
        cumarr[i] = sum;
    }
 
    // Update middle element
    int mid = (N - 1) / 2;
 
    // Calculate cost to convert
    // every element to mid element
    long long ans
        = (arr[mid] * (mid + 1)
           - cumarr[mid])
              * A
          + (cumarr[N - 1] - cumarr[mid]
             - (arr[mid] * (N - 1 - mid)))
                * B;
 
    if (A == B)
        return ans;
 
    else if (A < B) {
        int low = mid, high = N - 1;
 
        // Binary search
        while (low <= high) {
 
            mid = low + (high - low) / 2;
 
            long long curr
                = (arr[mid] * (mid + 1)
                   - cumarr[mid])
                      * A
                  + (cumarr[N - 1] - cumarr[mid]
                     - (arr[mid] * (N - 1 - mid)))
                        * B;
 
            if (curr <= ans) {
                ans = curr;
                low = mid + 1;
            }
            else
                high = mid - 1;
        }
 
        return ans;
    }
 
    else {
        int low = 0, high = mid;
 
        // Binary search
        while (low <= high) {
            mid = low + (high - low) / 2;
            long long curr
                = (arr[mid] * (mid + 1)
                   - cumarr[mid])
                      * A
                  + (cumarr[N - 1] - cumarr[mid]
                     - (arr[mid] * (N - 1 - mid)))
                        * B;
 
            if (curr <= ans) {
                ans = curr;
                high = mid - 1;
            }
            else
                low = mid + 1;
        }
 
        return ans;
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 2, 5, 6, 9, 10, 12, 15 };
    int A = 1, B = 2;
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << minCost(arr, A, B, N);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function to find minimum cost required
// to make all array elements equal
static int minCost(int[] arr, int A,
                   int B, int N)
{
     
    // Sort the array
    Arrays.sort(arr);
 
    // Stores the prefix sum and sum
    // of the array respectively
    int[] cumarr = new int[N];
    int sum = 0;
 
    // Traverse the array
    for(int i = 0; i < N; i++)
    {
         
        // Update sum
        sum += arr[i];
 
        // Update prefix sum
        cumarr[i] = sum;
    }
 
    // Update middle element
    int mid = (N - 1) / 2;
 
    // Calculate cost to convert
    // every element to mid element
    int ans = (arr[mid] * (mid + 1) - cumarr[mid]) *
                      A + (cumarr[N - 1] -
            cumarr[mid] - (arr[mid] * (N -
                      1 - mid))) * B;
               
    if (A == B)
        return ans;
         
    else if (A < B)
    {
        int low = mid, high = N - 1;
         
        // Binary search
        while (low <= high)
        {
            mid = low + (high - low) / 2;
 
            int curr = (arr[mid] * (mid + 1) -
                    cumarr[mid]) * A + (cumarr[N - 1] -
                     cumarr[mid] - (arr[mid] *
                              (N - 1 - mid))) * B;
 
            if (curr <= ans)
            {
                ans = curr;
                low = mid + 1;
            }
            else
                high = mid - 1;
        }
        return ans;
    }
 
    else
    {
        int low = 0, high = mid;
 
        // Binary search
        while (low <= high)
        {
            mid = low + (high - low) / 2;
            int curr = (arr[mid] * (mid + 1) -
                    cumarr[mid]) * A + (cumarr[N - 1] -
                     cumarr[mid] - (arr[mid] * (N - 1 -
                          mid))) * B;
 
            if (curr <= ans)
            {
                ans = curr;
                high = mid - 1;
            }
            else
                low = mid + 1;
        }
        return ans;
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int[] arr = { 2, 5, 6, 9, 10, 12, 15 };
    int A = 1, B = 2;
    int N = (int)(arr.length);
     
    System.out.println(minCost(arr, A, B, N));
}
}
 
// This code is contributed by susmitakundugoaldanga


Python3
# Python program to implement
# the above approach
 
# Function to find minimum cost required
# to make all array elements equal
def minCost(arr, A, B, N):
   
    # Sort the array
    arr.sort();
 
    # Stores the prefix sum and sum
    # of the array respectively
    cumarr = [0]*N;
    sum = 0;
 
    # Traverse the array
    for i in range(N):
       
        # Update sum
        sum += arr[i];
 
        # Update prefix sum
        cumarr[i] = sum;
 
    # Update middle element
    mid = (N - 1) // 2;
 
    # Calculate cost to convert
    # every element to mid element
    ans = (arr[mid] * (mid + 1) - cumarr[mid]) * A\
    + (cumarr[N - 1] - cumarr[mid] - (arr[mid] * (N - 1 - mid))) * B;
    if (A == B):
        return ans;
    elif (A < B):
        low = mid; high = N - 1;
 
        # Binary search
        while (low <= high):
            mid = low + (high - low) // 2;
            curr = (arr[mid] * (mid + 1) - cumarr[mid]) * A\
            + (cumarr[N - 1] - cumarr[mid] - (arr[mid] * (N - 1 - mid))) * B;
            if (curr <= ans):
                ans = curr;
                low = mid + 1;
            else:
                high = mid - 1;
        return ans;
    else:
        low = 0;
        high = mid;
 
        # Binary search
        while (low <= high):
            mid = low + (high - low) // 2;
            curr = (arr[mid] * (mid + 1) - cumarr[mid]) * A\
            + (cumarr[N - 1] - cumarr[mid] - (arr[mid] * (N - 1 - mid))) * B;
            if (curr <= ans):
                ans = curr;
                high = mid - 1;
            else:
                low = mid + 1;
        return ans;
 
# Driver Code
if __name__ == '__main__':
    arr = [2, 5, 6, 9, 10, 12, 15];
    A = 1; B = 2;
    N = (int)(len(arr));
 
    print(minCost(arr, A, B, N));
     
    # This code is contributed by 29AjayKumar


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG
{
 
    // Function to find minimum cost
    // required to make all array elements equal
    static ulong minCost(ulong[] arr, ulong A, ulong B,
                         ulong N)
    {
 
        // Sort the array
        Array.Sort(arr);
 
        // Stores the prefix sum and sum
        // of the array respectively
        ulong[] cumarr = new ulong[N];
        ulong sum = 0;
 
        // Traverse the array
        for (ulong i = 0; i < N; i++)
        {
 
            // Update sum
            sum += arr[i];
 
            // Update prefix sum
            cumarr[i] = sum;
        }
 
        // Update middle element
        ulong mid = (N - 1) / 2;
 
        // Calculate cost to convert
        // every element to mid element
        ulong ans = (arr[mid] * (mid + 1) - cumarr[mid]) * A
                    + (cumarr[N - 1] - cumarr[mid]
                       - (arr[mid] * (N - 1 - mid)))
                          * B;
        if (A == B)
            return ans;
        else if (A < B) {
            ulong low = mid, high = N - 1;
 
            // Binary search
            while (low <= high) {
 
                mid = low + (high - low) / 2;
 
                ulong curr
                    = (arr[mid] * (mid + 1) - cumarr[mid])
                          * A
                      + (cumarr[N - 1] - cumarr[mid]
                         - (arr[mid] * (N - 1 - mid)))
                            * B;
 
                if (curr <= ans) {
                    ans = curr;
                    low = mid + 1;
                }
                else
                    high = mid - 1;
            }
 
            return ans;
        }
 
        else {
            ulong low = 0, high = mid;
 
            // Binary search
            while (low <= high) {
                mid = low + (high - low) / 2;
                ulong curr
                    = (arr[mid] * (mid + 1) - cumarr[mid])
                          * A
                      + (cumarr[N - 1] - cumarr[mid]
                         - (arr[mid] * (N - 1 - mid)))
                            * B;
 
                if (curr <= ans) {
                    ans = curr;
                    high = mid - 1;
                }
                else
                    low = mid + 1;
            }
            return ans;
        }
    }
 
    // Driver Code
    public static void Main()
    {
        ulong[] arr = { 2, 5, 6, 9, 10, 12, 15 };
        ulong A = 1, B = 2;
        ulong N = (ulong)(arr.Length);
        Console.Write(minCost(arr, A, B, N));
    }
}
 
// This code is contributed by subhammahato348


Javascript


输出:
32

时间复杂度: O(N)
辅助空间: O(N)