首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DP -硬币兑换计数

DP -硬币兑换计数
EN

Stack Overflow用户
提问于 2012-08-08 08:56:54
回答 3查看 2.7K关注 0票数 0

这个问题需要为特定的成本计算硬币变化的数量。

例如,如果我有50, 20, 10, 5, 1的硬币值,我可以形成以下的成本:

5 => (5),(11111),这是两种途径。

10 => (10),(5,5),(5,11111),(11111,11111),这四种方式。

这是我的功能。它正在从10的成本中返回错误的结果(返回9条,而实际的方法只有4条)。

代码语言:javascript
复制
int dp[10000];
int coins[] = { 50, 20, 10, 5, 1 };
int rec(int n)
{
  if (n == 0) return 1;
  if (dp[n] != -1) return dp[n];
  int cnt = 0;
  for (int i = 0; i < 5; i++)
    if (coins[i] <= n) cnt += rec(n - coins[i]);
  return dp[n] = cnt;
}

我如何修正这个函数以给出正确的方法数目?这个算法是否正确?请参阅完整的代码及其输出这里

注意到:我的问题不是dp数组初始化。在调用memset之前,我每次都使用-1将其初始化为rec

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-08-08 09:17:42

(5,1,1,1,1,1)和(1,1,1,5,1,1)在你的算法中是不同的,你应该保持它的减少。

代码语言:javascript
复制
int dp[10000][5];  // dp[20][2] means, if the biggest coin is coins[2],
                   // how much ways for 20 ?
int coins[] = { 1, 5, 10, 20, 50 }; // here
int rec(int n, int m)
{
  int cnt = 0;
  int i;
  if (n == 0) return 1;
  //if (m == 0) return 1;
  if (dp[n][m] != -1) return dp[n][m];
  for (i = 0; i <= m; i++)
    if (coins[i] <= n) cnt += rec(n - coins[i], i);
  return dp[n][m] = cnt;
}

int main()
{
        memset(dp, -1, sizeof(dp));
        printf("%d\n", rec(10, 4));
}
票数 3
EN

Stack Overflow用户

发布于 2012-08-08 09:08:46

结果是错误的,因为你从来没有确保你的算法开始于5枚硬币。( 5,11111)在代码中与(1,5,1111)一样有效,但这是相同的结果。你的结果应该是错误的,从6和更高,而不是10和更高。

要解决这个问题,您可以像函数rec()中的一个截止项一样:

代码语言:javascript
复制
int rec(int n, int cutoff)
{
  if (n == 0) return 1;
  if (dp[n] != -1) return dp[n];
  int cnt = 0;
  for (int i = cutoff; i < 5; i++)
    if (coins[i] <= n) cnt += rec(n - coins[i], i);
  return dp[n] = cnt;
}

应该这么做。

编辑:您必须照顾您的dp[]数组,因为它不关心这个截止值,但这通常是您遇到的错误。您可以注释这一行,并检查这是否有效。

票数 1
EN

Stack Overflow用户

发布于 2012-08-08 09:12:18

注意:你的初始化

代码语言:javascript
复制
memset(dp, -1, sizeof dp);

不太安全。memset初始化内存空间的每个字节(参见http://www.cplusplus.com/reference/clibrary/cstring/memset/.)。对于这种特殊情况,您是幸运的,int(-1)的表示(可能)与四次unsigned char(-1)的表示相同。

我建议使用std::fill ( http://www.cplusplus.com/reference/algorithm/fill/ )。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11861038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档