您的位置:首页 > 其它

最少硬币问题 动态规划

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);
}

}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 动态规划