【动态规划】之硬币找零问题(难度:1星)
2017-12-14 22:56
274 查看
#include <stdio.h> /** * 原题: * 假设有几种硬币,如1块、3块、5块,并且数量无限。 * 请找出能够组成某个数目的找零所使用最少的硬币数。 */ #define MIN(x,y) (x<y?x:y) #define INF 50000 //一个很大的值,这里可看作无限大 #define N 5 //有5种硬币 #define K 22 //目标为K块 static int a[N] = {1,3,5,6,7}; //每种硬币的面值 /** * 我的思路如下 * 设子问题为:请求出用N种硬币,能够组成目标数值k(k<=K)的最小硬币数minSum * 找出边界:显然k=0时,minSum=0,因为凑够0元需要的硬币数肯定是0个 */ //最容易想到的是递归 int solve_1(int k){ if (k == 0) return 0; int minSum = INF; for (int i = 0; i < N; ++i) { //如果当前硬币面值不大于目标值,比较并求出最小的硬币数 if (k >= a[i]) { minSum = MIN(minSum, solve_1(k - a[i]) + 1); } } return minSum; } //solve_1基础上可以加一个记忆数组 static int memo[K+1]; int solve_2(int k){ if (memo[k] < INF) return memo[k]; if (k == 0) return memo[k] = 0; int minSum = INF; for (int i = 0; i < N; ++i) { //如果当前硬币面值不大于目标值,比较并求出最小的硬币数 if (k >= a[i]) { minSum = MIN(minSum, solve_2(k - a[i]) + 1); } } return memo[k] = minSum; } //改良solve_2成为递推 static int minSum[K+1]; int solve_3(){ minSum[0] = 0; for (int i = 1; i <= K; ++i) { minSum[i] = INF; } for (int i = 1; i <= K; ++i) { for (int j = 0; j < N; ++j) { //如果当前硬币面值不大于目标值,比较并求出最小的硬币数 if (i >= a[j]){ minSum[i] = MIN(minSum[i], minSum[i-a[j]] + 1); } } } return minSum[K]; } int main() { printf("solve_1:%d\n", solve_1(K)); for (int i = 0; i < K+1; ++i) { memo[i] = INF; } printf("solve_2:%d\n", solve_2(K)); // for (int i = 0; i < K+1; ++i) { // printf("%d ", memo[i]); // } printf("\nsolve_3:%d\n", solve_3()); // for (int i = 0; i < K+1; ++i) { // printf("%d ", minSum[i]); // } return 0; }
运行结果:
solve_1:4
solve_2:4
solve_3:4
相关文章推荐
- 动态规划入门之硬币找零问题
- 硬币找零问题 - 动态规划
- 动态规划求解最多有几种方案求解硬币找零问题
- 硬币找零问题(动态规划)
- 最少硬币找零问题-动态规划
- 硬币找零问题(动态规划求解)
- 动态规划之最少硬币找零问题
- 动态规划求解硬币找零问题——Java实现
- 人民币找零 vs 硬币问题 贪心 vs 动态规划
- 硬币找零问题_动态规划_算法与数据结构
- 最少硬币找零问题-动态规划
- 硬币找零问题,力求解决一些一切可能的办法,硬币的最小数量,有多少每个硬币的
- 动态规划只11硬币的问题
- 动态规划入门之硬币问题(转)
- dp 硬币找零问题
- 硬币找零-记忆化搜索(DP动态规划)
- 动态规划-背包问题降维以及衍生的硬币问题
- 动态规划 找零问题
- 动态规划算法求解硬币找零问题(1)
- 硬币收集问题--动态规划3