📌  相关文章
📜  总和等于给定数量的最小元素数

📅  最后修改于: 2021-05-04 23:52:44             🧑  作者: Mango

给定形式的元素的无限个10^n25*100^n (n> = 0)。任务是找到所选元素的最小数量,以使总和等于K。

例子:

方法:
以下元素数量不限:
1、10、25、100、1000、2500、10000、100000、250000…等等。

贪婪方法在这里行不通。对于K = 66,通过贪婪方法最小计数将是9和选择元件25 + 25 + 10 + 1 + 1 + 1 + 1 + 1 + 1 = 66。但是,其最佳答案是6时这些元件选自:25 + 10 + 10 + 10 + 10 + 1 =66。因此,动态编程将在此处工作。但是不能应用简单的DP,因为K可以达到10 ^ 9。
动态编程方法:

  • 预先计算最小编号所选择的构成总和最多为99的元素并将其存储在备忘录数组中。
  • 同样,最多只能由1、10和25的组合来形成总和为99。
  • 从K的末尾开始,对每最后2位数字进行迭代以找到最小编号。所选元素的总和为最后两位数。
  • 将它们全部求和以找到最小数量。

下面是上述方法的实现。

C++
// C++ implementation of the above approach
#include 
using namespace std;
  
int minCount(int K)
{
    // we will only store min counts
    // of sum upto 100
    int memo[100];
  
    // initialize with INT_MAX
    for (int i = 0; i < 100; i++) {
        memo[i] = INT_MAX;
    }
  
    // memo[0] = 0 as 0 is
    // made from 0 elements
    memo[0] = 0;
  
    // fill memo array with min counts
    // of elements that will constitute
    // sum upto 100
  
    for (int i = 1; i < 100; i++) {
        memo[i] = min(memo[i - 1] + 1, memo[i]);
    }
  
    for (int i = 10; i < 100; i++) {
        memo[i] = min(memo[i - 10] + 1, memo[i]);
    }
  
    for (int i = 25; i < 100; i++) {
        memo[i] = min(memo[i - 25] + 1, memo[i]);
    }
  
    // min_count will store min
    // count of elements chosen
    long min_count = 0;
  
    // starting from end iterate over
    // each 2 digits and add min count
    // of elements to min_count
    while (K > 0) {
        min_count += memo[K % 100];
        K /= 100;
    }
  
    return min_count;
}
  
// Driver code
int main()
{
  
    int K = 69;
  
    cout << minCount(K) << endl;
  
    return 0;
}


Java
// Java implementation of the above approach 
  
class GFG
{
      
    static int minCount(int K) 
    { 
        // we will only store min counts 
        // of sum upto 100 
        int memo[] = new int[100]; 
      
        // initialize with INT_MAX 
        for (int i = 0; i < 100; i++) 
        { 
            memo[i] = Integer.MAX_VALUE; 
        } 
      
        // memo[0] = 0 as 0 is 
        // made from 0 elements 
        memo[0] = 0; 
      
        // fill memo array with min counts 
        // of elements that will constitute 
        // sum upto 100 
      
        for (int i = 1; i < 100; i++) 
        { 
            memo[i] = Math.min(memo[i - 1] + 1, memo[i]); 
        } 
      
        for (int i = 10; i < 100; i++) 
        { 
            memo[i] = Math.min(memo[i - 10] + 1, memo[i]); 
        } 
      
        for (int i = 25; i < 100; i++) 
        { 
            memo[i] = Math.min(memo[i - 25] + 1, memo[i]); 
        } 
      
        // min_count will store min 
        // count of elements chosen 
        int min_count = 0; 
      
        // starting from end iterate over 
        // each 2 digits and add min count 
        // of elements to min_count 
        while (K > 0)
        { 
            min_count += memo[K % 100]; 
            K /= 100; 
        } 
      
        return min_count; 
    } 
      
    // Driver code 
    public static void main (String[] args) 
    {
          
                int K = 69; 
      
                System.out.println(minCount(K)); 
    }
}
  
// This code is contributed by AnkitRai01


Python3
# Python3 implementation of the above approach
  
def minCount(K):
      
    # we will only store min counts
    # of sum upto 100
    memo=[10**9 for i in range(100)]
  
    # memo[0] = 0 as 0 is
    # made from 0 elements
    memo[0] = 0
  
    # fill memo array with min counts
    # of elements that will constitute
    # sum upto 100
  
    for i in range(1,100):
        memo[i] = min(memo[i - 1] + 1, memo[i])
  
    for i in range(10,100):
        memo[i] = min(memo[i - 10] + 1, memo[i])
  
    for i in range(25,100):
        memo[i] = min(memo[i - 25] + 1, memo[i])
  
    # min_count will store min
    # count of elements chosen
    min_count = 0
  
    # starting from end iterate over
    # each 2 digits and add min count
    # of elements to min_count
    while (K > 0):
        min_count += memo[K % 100]
        K //= 100
  
    return min_count
  
# Driver code
  
K = 69
  
print(minCount(K))
  
# This code is contributed by mohit kumar 29


C#
// C# implementation of the above approach 
using System;
  
class GFG
{
          
    static int minCount(int K) 
    { 
        // we will only store min counts 
        // of sum upto 100 
        int []memo = new int[100]; 
      
        // initialize with INT_MAX 
        for (int i = 0; i < 100; i++) 
        { 
            memo[i] = int.MaxValue; 
        } 
      
        // memo[0] = 0 as 0 is 
        // made from 0 elements 
        memo[0] = 0; 
      
        // fill memo array with min counts 
        // of elements that will constitute 
        // sum upto 100 
      
        for (int i = 1; i < 100; i++) 
        { 
            memo[i] = Math.Min(memo[i - 1] + 1, memo[i]); 
        } 
      
        for (int i = 10; i < 100; i++) 
        { 
            memo[i] = Math.Min(memo[i - 10] + 1, memo[i]); 
        } 
      
        for (int i = 25; i < 100; i++) 
        { 
            memo[i] = Math.Min(memo[i - 25] + 1, memo[i]); 
        } 
      
        // min_count will store min 
        // count of elements chosen 
        int min_count = 0; 
      
        // starting from end iterate over 
        // each 2 digits and add min count 
        // of elements to min_count 
        while (K > 0)
        { 
            min_count += memo[K % 100]; 
            K /= 100; 
        } 
      
        return min_count; 
    } 
      
    // Driver code 
    static public void Main ()
    {
          
        int K = 69; 
        Console.WriteLine(minCount(K)); 
    }
}
  
// This code is contributed by ajit


输出:
9