【问题标题】:algorithm-coin changing code mistake算法硬币换码错误
【发布时间】:2014-08-03 05:17:44
【问题描述】:

给定一个 N 值,如果我们想找 N 美分,并且我们有无限供应 S = { S1, S2, .. , Sm} 价值的硬币,我们有多少种方法可以找零?硬币的顺序无关紧要。

我写了下面的代码,但它总是返回比实际答案少一。我想知道这是否是编写解决方案的正确方法?

#include <stdio.h>

int ways=0;
int remember[100] = {0};

void foo(int coin_denomination[], int size, int sum)
{
    int i;
    printf("%d\n", sum);
    if (sum==0) {
        ways++; 
        return; 
    }   
    if (remember[sum]==1)
        return; 
    remember[sum] = 1;
    if (sum < 0)
        return; 
    for(i=0;i<size;i++)
        foo(coin_denomination, size, sum-coin_denomination[i]);
}

int main()
{
    int coin_denomination[] = {1, 2, 3}; 
    int sum = 5;

    foo(coin_denomination, sizeof(coin_denomination)/sizeof(coin_denomination[0]), sum);
    printf("%d\n", ways);
    return 0;
}

【问题讨论】:

  • 你说它总是返回比实际答案少一个:也许你需要更多的测试用例。

标签: c algorithm recursion coin-change


【解决方案1】:

您需要对foo 方法进行一些更改。您的问题是使用变量 remember 您没有计算一些解决方案。变量remember 的目标不正确,您使用的不是多次处理相同的硬币收集,但您只保存了硬币收集的总和和可以通过多个硬币收藏获得总和(例如:1 1 11 2 的总和相同,当您选择第二个时,remember[3] 将是 1 并且不会通过这一点,缺少解决方案 1 2 2

需要其他不重复coin collection的方式,在这种情况下,添加一个参数表示正在处理的coin_denomination的索引,并且只允许处理之后的硬币,问题就解决了。

代码(使用 GCC 4.9.0 测试):

#include <stdio.h>

int ways=0;

void foo(int coin_denomination[], int size, int sum, int coin_idx = 0)
{
    if (sum < 0)
        return;
    int i;
    printf("%d\n", sum);
    if (sum==0) {
        ways++; 
        return; 
    }   
    for(i=coin_idx;i<size;i++)
        foo(coin_denomination, size, sum-coin_denomination[i], i);
}

int main()
{
    int coin_denomination[] = {1, 2, 3}; 
    int sum = 5;

    foo(coin_denomination, sizeof(coin_denomination)/sizeof(coin_denomination[0]), sum);
    printf("%d\n", ways);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多