dp算法之硬币找零问题

题目:硬币找零

题目介绍:现在有面值1、3、5元三种硬币无限个,问组成n元的硬币的最小数目?

分析:现在假设n=10,画出状态分布图:

硬币编号硬币面值p
11
23
35

 

编号i/n总数j012345678910
1012345678910
201212323434
301212123232

设所需硬币最小数目为m,则可以看出m[ i ][  j ]=m[ i-1 ][  j-k*p[ i ]] + k.其中k*p[ i ]<=j.确切的说,k=j/p[ i ].

dp算法的显著特征之一就是具有最优子结构,且这一状态的最优解与上一状态的最优解有关。写出状态方程之后我们就可以开始具体处理代码了。

 1 #include <iostream>
 2 using namespace std;
 3 int main()
 4 {
 5     int i, j, k;
 6     int m, n;//m就是总值
 7     cout << "总数:" << endl;
 8     cin >> m;
 9     //m = 10, ;
10     n = 3;
11     int **c = new int *[n + 1];
12     for (i = 0; i <= n; i++)
13     {
14         c[i] = new int[m + 1];
15     }
16     int p[4] = { 0,1,3,5 };
17     for (i = 0; i <= n; i++)
18     {
19         for (j = 0; j <= m; j++)
20         {
21             c[i][j] = 0;//初始化
22         }
23     }
24     for (i = 1; i <= n; i++)
25     {
26         for (j = 1; j <= m; j++)
27         {
28             k = j / p[i];
29             c[i][j] = c[i - 1][j - k * p[i]] + k;
30         }
31     }
32     for (i = 1; i <= n; i++)
33     {
34         for (j = 0; j <= m; j++)
35         {
36             cout << c[i][j] << " ";
37         }
38         cout << endl;
39     }
40     return 0;
41 }

分析:这个硬币找零问题在dp算法中比较经典,复杂度低于经典的背包问题,因为背包问题还要考虑 k 的值,需要遍历 k 的值来找到一个最优解,此题不需要。

结果:

下一篇将要分析经典的背包问题了,包括01背包、完全背包、多重背包。

 

转载于:https://www.cnblogs.com/ljy1227476113/p/9675145.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值