📌  相关文章
📜  总和为给定数字的元素的最小计数

📅  最后修改于: 2021-09-22 10:10:49             🧑  作者: Mango

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

方法:
以下元素有无数个:
1、10、25、100、1000、2500、10000、100000、250000……等等。
贪婪的方法在这里不起作用。 For K = 66, by Greedy Approach minimum count will be 9 and chosen elements are 25 + 25 + 10 + 1 + 1 + 1 + 1 + 1 + 1 = 66. But its optimum answer is 6 when these elements are chosen: 25 + 10 + 10 + 10 + 10 + 1 = 66。因此,动态规划将在这里起作用。但是不能应用简单的 DP,因为 K 可以达到 10^9 。
动态规划方法:

  • 预先计算最小数量。选择的元素构成总和达 99 并将其存储在备忘录数组中。
  • 此外,最多 99 的和只能由 1、10 和 25 的组合构成。
  • 从 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


Javascript


输出:
9

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程