计算进行更改的方式数

时间:2013-03-06 06:54:30

标签: c++ c algorithm subset-sum coin-change

我有一套硬币1,2,4,10,20,40,100,200,400,1000,2000美分。我想找出支付一定金额的多少种方式(< = 6000)。我目前在c ++中的解决方案是使用动态编程如下:

long long d[6010];
int coin[] = {1, 2, 4, 10, 20, 40, 100, 200, 400, 1000, 2000};
d[0] = 1;
for (int i = 0; i < 11; i++) {  // iterate through all coins
    for (int j = 1; j <= 6000; j++)
        d[j] += d[j - coin[i]];
printf("%lld\n", d[20]);

但是我的输出不正确:-956301262。是因为任何溢出问题吗?

3 个答案:

答案 0 :(得分:2)

您必须使用大小为6001x11的二维数组(在您的情况下)来存储所有可能的值。从d [0] [0]开始并迭代直到d [6000] [10],其中包含最终答案。

答案 1 :(得分:1)

我没有看到你的算法应该如何工作,我会在从高到低的每个面额上递归递归(循环不同的量)。使用查找表时,可能与您的d相似。

有些事情:

howmanyways(sorted_denominations_set_starting_with_1, target amount):
if this is already in the lookup table return the result
else if sorted_denominations_set_starting_with_1 is {1}, then return target amount
else loop over 0 to target amount/last_set_element
   return the sum of results for howmanyways(sorted_denominations_set_starting_with_1 without the largest element, target amount-last_set_element*loop_index)
keep whatever you return in the lookup table

并返回howmanyways({1,2,4,10,20,40,100,200,400,1000,2000},目标金额);

答案 2 :(得分:1)

你的循环是倒退的。硬币面额循环应该是你的内循环。

您的阵列分配也没有意义。您目前只是通过硬币的特定面额来总结与目标不同的变化值。

你应该有一个矢量矢量作为你的数据结构。每次运行内循环时,都应该在数据结构中插入一个新的向量。该向量应该是一组硬币,其总和等于感兴趣的值。