给定无限数量的形式元素和 ( n >= 0 )。任务是找到所选元素的最小数量,以便总和等于K 。
例子:
Input : K = 48
Output : 6
elements chosen are: (1 + 1 + 1 + 10 + 10 + 25)
Input : 69
Output : 9
elements chosen are: (1 + 1 + 1 + 1 + 10 + 10 + 10 + 10 + 25)
方法:
以下元素有无数个:
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 位数字以找到最小编号。所选元素的总和为最后两位数字。
- 将它们全部相加以找到最小计数。
Illustration of the above approach:
Let’s take K = 250166
Let min_count = 0, last 2 digits = 66
add minimum number of elements to min_count that sums to 66 (it is calculated from memo array
that we have precomputed).
min_count = min_count + 6,
Now, min_count = 6, last 2 digits = 01
add minimum number of elements to min_count sums to 1.
min_count = min_count + 1,
Now, min_count = 7, last 2 digits = 25
add minimum number of elements to min_count sums to 25.
min_count = min_count + 1,
Now, min_count = 8.
So, minimum number of elements chosen that sums to 250166 is 8.
Optimal chosen Elements are (250000, 100, 25, 10, 10, 10, 10, 1)
下面是上述方法的实现。
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 现场工作专业课程和学生竞争性编程现场课程。