动态规划题目(一)——换零钱

布满荆棘的人生 2022-08-06 01:07 306阅读 0赞

动态规划题目(一)——换零钱

1. 题目描述

想兑换100元钱,有1,2,5,10四种钱,问总共有多少兑换方法。

下面提供两种实现方式,其中代码注释的很清楚。

关于动态规划的基本原理,参考:

http://www.cnblogs.com/sdjl/articles/1274312.html

2. 递归解法

  1. //动态规划
  2. #include<iostream>
  3. using namespace std;
  4. const int N = 100;
  5. int dimes[] = {1, 2, 5, 10};
  6. int arr[N+1] = {1};
  7. int coinExchangeRecursion(int n, int m) //递归方式实现,更好理解
  8. {
  9. if (n == 0) //跳出递归的条件
  10. return 1;
  11. if (n < 0 || m == 0)
  12. return 0;
  13. return (coinExchangeRecursion(n, m-1) + coinExchangeRecursion(n-dimes[m-1], m));
  14. //分为两种情况,如果没有换当前硬币,那么是多少?加上,如果换了当前硬币,总值减少,此时又是多少种兑换方法?
  15. }
  16. int main()
  17. {
  18. int num=coinExchangeRecursion(N, 4);
  19. cout<<num<<endl;
  20. int num2=coinExchange(N);
  21. cout<<num2<<endl;
  22. return 0;
  23. }

3. 非递归解法

  1. //动态规划
  2. #include<iostream>
  3. using namespace std;
  4. const int N = 100;
  5. int dimes[] = {1, 2, 5, 10};
  6. int arr[N+1] = {1};
  7. int coinExchange(int n) //非递归实现
  8. {
  9. int i, j;
  10. for (i = 0; i < sizeof(dimes)/sizeof(int); i++) //i从0 ~ 3 因为每个arr[j]都要有一次是假设兑换了dimes[i],所以我们要遍历一次
  11. {
  12. for (j = dimes[i]; j <= n; j++)
  13. //求,arr[j]的时候,可以看出arr[j] = arr[j] + arr[j-dimes[i]],
  14. //对应着上面的递归方式:arr[j]就是coinExchangeRecursion(n, m-1),
  15. //arr[j-dimes[i]]就是coinExchangeRecursion(n-dimes[m-1], m)
  16. arr[j] += arr[j-dimes[i]];
  17. }
  18. return arr[n];
  19. }
  20. int main()
  21. {
  22. int num=coinExchangeRecursion(N, 4);
  23. cout<<num<<endl;
  24. int num2=coinExchange(N);
  25. cout<<num2<<endl;
  26. return 0;
  27. }

大家可以看出来,递归方式求解比较便于理解。当时,我们一定也要掌握非递归方式的实现,虽然它不太好想,例如上面的

  1. arr[j] += arr[j-dimes[i]];

这一句。当时非递归方式的有效性是有目共睹的!

发表评论

表情:
评论列表 (有 0 条评论,306人围观)

还没有评论,来说两句吧...

相关阅读

    相关 零钱--动态规划

    题目示例: 【题目】 给定数组arr,arr中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求换钱有