最少硬币问题 动态规划
2016-05-30 20:42
579 查看
问题描述
需要找零x元,有n种面值硬币,求找零最少需要硬币个数的方法。问题分析
这题如果用贪心算法做,很可能无法得到最优解甚至无法无法找零,比如要找零11元,有{5,6,10}三种硬币,最优解是{5,6},用贪心就会先用10块钱去消耗,那这题就无法完成。所以这题用动态规划最合适,利用递推和缓存,动态规划将问题拆分成若干个子问题,通过子问题的最优解不断往上递推得出问题的最优解,这比贪心算法慢,但得到的答案跟准确。
代码
#include<stdio.h> void minCoin(int cost, int coinType[], int typeNum); void main() { int cost = 18; //找零面值 int coinType[5] = { 1,2,5,9,10 }; //纸币面额 // int coinType[2] = { 3,4 }; //TEST const int typeNum = sizeof(coinType) / sizeof(coinType[1]);//种类数量 //int coinUsed[typeNum + 1]; coinUsed[0] = 0;// 1-cost 找零各需要多少硬币 minCoin(cost, coinType, typeNum); } void minCoin(int cost, int coinType[], int typeNum) { int *coinUsed = new int[typeNum + 1]; coinUsed[0] = 0;// 1-cost 找零各需要多少硬币 int *addHistroy = new int[typeNum + 1]; addHistroy[0] = 0; //记录每次增加的硬币 for (int i = 1; i <= cost; i++) //从1块钱开始计数 { coinUsed[i] = 9999999; //当9999999时表示无法找零 for (int t = 0; t < typeNum; t++) { if (i >= coinType[t]) { if (coinUsed[i - coinType[t]] + 1 <= coinUsed[i]) { coinUsed[i] = coinUsed[i - coinType[t]] + 1; addHistroy[i] = coinType[t]; } } } /* coinUsed[i]==9999999? printf("无法找零\n") : printf("找%d块钱最少需要%d个硬币\n",i, coinUsed[i]); 测试*/ } if (coinUsed[cost] != 9999999) { printf("找%d块钱最少需要%d个硬币 如下:\n", cost, coinUsed[cost]); while (cost > 0) { printf("%d ", addHistroy[cost]); cost = cost - addHistroy[cost]; } } else { printf("无法找%d块钱\n",cost); } }
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析