📜  使给定数组中最多 S 的数组求和的最小操作

📅  最后修改于: 2022-05-13 01:56:10.449000             🧑  作者: Mango

使给定数组中最多 S 的数组求和的最小操作

给定一个大小为N的数组arr[]和一个整数S ,任务是找到使数组之和小于或等于S的最小操作。在每个操作中:

  • 可以选择任何元素,并且可以减 1,或者
  • 可以被数组中的任何其他元素替换。

例子:

方法:这个问题可以使用贪心方法和通过对数组排序的后缀求和来解决。对最小元素应用第一个操作任意次数,然后通过在第一个操作后将其替换为最小元素来对后缀应用第二个操作给出最小操作。

按照以下步骤解决上述问题:

  • 将变量sum = 0和数组的大小初始化为N
  • 遍历向量并找到数组的总和。
  • 如果sum < = S打印 0 并返回。
  • 对向量进行排序并分配diff = sum-S
  • 初始化ops = sum-S ,这是最大可能的操作。
  • 初始化s =0存储向量的后缀和。
  • 现在使用 for 循环从向量的末尾遍历。
  • 跟踪s变量中的后缀总和
  • 初始化一个dec变量,该变量是要从数组的后缀递减的值
    • 如果s-dec大于或等于diff ,则无需递减arr[0] ,因此分配x =0
    • 否则找到x的值,它是arr[0]中要递减的值,并找到最小操作。
  • 打印最少的操作

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to divide and get the ceil value
int ceil_div(int a, int b)
{
    return a / b + ((a ^ b) > 0 && a % b);
}
 
// Function to find the minimum cost
void minimum_cost(vector arr, int S)
{
    int sum = 0;
    int n = arr.size();
     
    // Find the sum of the array
    for (int i = 0; i < arr.size(); i++) {
        sum += arr[i];
    }
     
    // If sum <= S no operations required
    if (sum <= S) {
        cout << 0 << endl;
        return;
    }
     
    // Sort the array
    sort(arr.begin(), arr.end());
 
    int diff = sum - S;
     
    // Maximum it requires sum-S operations
    // by decrementing
    // the arr[0] by 1
    int ops = sum - S;
    // suffix sum
    int s = 0;
    int x;
 
    for (int i = n - 1; i > 0; i--) {
        s += arr[i];
         
        // If replacing the last elements
        // with doing the first operation
        // x = 0 Decrementing the a[i] from
        // the suffix [i,n-1]
        int dec = (n - i) * arr[0];
        if (s - dec >= diff) {
            x = 0;
        }
         
        // Find how times the first element
        // should be decremented by 1 and
        // incremented by 1 which is x
        else {
            x = max(ceil_div((diff - s + dec),
                             (n - i + 1)), 0);
        }
         
        // First operation + second operation
        if (x + n - i < ops) {
            ops = x + n - i;
        }
    }
 
    // Print the operations
    cout << ops << endl;
}
 
// Driver code
int main()
{
    // Initialize the array
    vector arr = { 1, 2, 1, 3, 1, 2, 1 };
    int S = 8;
     
    // Function call
    minimum_cost(arr, S);
 
    return 0;
}


Java
// Java program for the above approach
 
import java.util.Arrays;
 
class GFG {
 
  // Function to divide and get the ceil value
  static int ceil_div(int a, int b) {
    int temp = 0;
    if (((a ^ b) > 0) && ((a % b) > 0)) {
      temp = 1;
    }
    return (a / b) + temp;
  }
 
  // Function to find the minimum cost
  static void minimum_cost(int[] arr, int S) {
    int sum = 0;
    int n = arr.length;
 
    // Find the sum of the array
    for (int i = 0; i < arr.length; i++) {
      sum += arr[i];
    }
 
    // If sum <= S no operations required
    if (sum <= S) {
      System.out.println(0);
      return;
    }
 
    // Sort the array
    Arrays.sort(arr);
 
    int diff = sum - S;
 
    // Maximum it requires sum-S operations
    // by decrementing
    // the arr[0] by 1
    int ops = sum - S;
    // suffix sum
    int s = 0;
    int x;
 
    for (int i = n - 1; i > 0; i--) {
      s += arr[i];
 
      // If replacing the last elements
      // with doing the first operation
      // x = 0 Decrementing the a[i] from
      // the suffix [i,n-1]
      int dec = (n - i) * arr[0];
      if (s - dec >= diff) {
        x = 0;
      }
 
      // Find how times the first element
      // should be decremented by 1 and
      // incremented by 1 which is x
      else {
        x = Math.max(ceil_div((diff - s + dec),
                              (n - i + 1)), 0);
      }
 
      // First operation + second operation
      if (x + n - i < ops) {
        ops = x + n - i;
      }
    }
 
    // Print the operations
    System.out.println(ops);
  }
 
  // Driver code
  public static void main(String args[])
  {
 
    // Initialize the array
    int[] arr = { 1, 2, 1, 3, 1, 2, 1 };
    int S = 8;
 
    // Function call
    minimum_cost(arr, S);
  }
}
 
// This code is contributed by saurabh_jaiswal.


Python3
# Python 3 program for the above approach
 
# Function to divide and get the ceil value
def ceil_div(a,  b):
 
    return a // b + ((a ^ b) > 0 and a % b)
 
# Function to find the minimum cost
def minimum_cost(arr, S):
 
    sum = 0
    n = len(arr)
 
    # Find the sum of the array
    for i in range(len(arr)):
        sum += arr[i]
 
    # If sum <= S no operations required
    if (sum <= S):
        print(0)
        return
 
    # Sort the array
    arr.sort()
 
    diff = sum - S
 
    # Maximum it requires sum-S operations
    # by decrementing
    # the arr[0] by 1
    ops = sum - S
    # suffix sum
    s = 0
 
    for i in range(n - 1, -1, -1):
        s += arr[i]
 
        # If replacing the last elements
        # with doing the first operation
        # x = 0 Decrementing the a[i] from
        # the suffix [i,n-1]
        dec = (n - i) * arr[0]
        if (s - dec >= diff):
            x = 0
 
        # Find how times the first element
        # should be decremented by 1 and
        # incremented by 1 which is x
        else:
            x = max(ceil_div((diff - s + dec),
                             (n - i + 1)), 0)
 
        # First operation + second operation
        if (x + n - i < ops):
            ops = x + n - i
 
    # Print the operations
    print(ops)
 
# Driver code
if __name__ == "__main__":
 
    # Initialize the array
    arr = [1, 2, 1, 3, 1, 2, 1]
    S = 8
 
    # Function call
    minimum_cost(arr, S)
 
    # This code is contributed by ukasp.


C#
// C# program for the above approach
using System;
class GFG
{
  // Function to divide and get the ceil value
  static int ceil_div(int a, int b) {
    int temp = 0;
    if (((a ^ b) > 0) && ((a % b) > 0)) {
      temp = 1;
    }
    return (a / b) + temp;
  }
 
  // Function to find the minimum cost
  static void minimum_cost(int[] arr, int S) {
    int sum = 0;
    int n = arr.Length;
 
    // Find the sum of the array
    for (int i = 0; i < arr.Length; i++) {
      sum += arr[i];
    }
 
    // If sum <= S no operations required
    if (sum <= S) {
      Console.WriteLine(0);
      return;
    }
 
    // Sort the array
    Array.Sort(arr);
 
    int diff = sum - S;
 
    // Maximum it requires sum-S operations
    // by decrementing
    // the arr[0] by 1
    int ops = sum - S;
    // suffix sum
    int s = 0;
    int x;
 
    for (int i = n - 1; i > 0; i--) {
      s += arr[i];
 
      // If replacing the last elements
      // with doing the first operation
      // x = 0 Decrementing the a[i] from
      // the suffix [i,n-1]
      int dec = (n - i) * arr[0];
      if (s - dec >= diff) {
        x = 0;
      }
 
      // Find how times the first element
      // should be decremented by 1 and
      // incremented by 1 which is x
      else {
        x = Math.Max(ceil_div((diff - s + dec),
                              (n - i + 1)), 0);
      }
 
      // First operation + second operation
      if (x + n - i < ops) {
        ops = x + n - i;
      }
    }
 
    // Print the operations
    Console.Write(ops);
  }
 
  // Driver code
  public static void Main()
  {
 
    // Initialize the array
    int[] arr = { 1, 2, 1, 3, 1, 2, 1 };
    int S = 8;
 
    // Function call
    minimum_cost(arr, S);
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript



输出
2

时间复杂度: O(N* logN)
空间复杂度: O(1)