贪心算法--找换硬币
找换硬币
考虑用最少的硬币数来找N分钱的问题,假设每个硬币的值都是整数。
a) 请给出一个贪心算法,使得所换硬币包括一角的,五分的,二角五分的和一分的。证明所给出的算法能产生最优解。
b) 假设可换的硬币的单位是c的幂,也就是c^0,c^1,c^2,c^3……其中整数c>1,k>=1。证明贪心算法总可以产生一个最优解。
c) 请给出一组是贪心算法不能产生最优解的硬币单位集合。所给集合应当包括一分,以便保证对任意n值都有解。
d) 请给出一种O(nk)时间的算法,它能够对任意K种不同单位的硬币集合进行找换,假设其中一种硬币单位是一分的。
解:
a) 找换硬币的贪心算法思想:
(1)将找换集合中的元素进行降序排列,CurrentMax指向首元素;
(2)判断N是否大于找换集合中当前最大元素,如果大于,N=N-CurrentMax;再执行此步骤。如果不大于,则找换集合中的CurrentMax指向下一个元素,执行此步骤。
(3)若N=0,则找到了找换硬币的方法。
算法的源代码:
#include<stdio.h>
int main()
{
freopen("data.out","w",stdout);
int money,s1,s2,s3,s4,p,d,n,q,temp;
scanf("%d%d%d%d%d",&money,&s1,&s2,&s3,&s4);
temp=money;
p = money/s1;
if (p >0)
money -= p*s1;
d = money/s2;
if (d >0)
money -= d*s2;
n = money/s3;
if (n >0)
money -= n*s3;
q = money/s4;
if (temp==(p*s1+d*s2+n*s3+q))
{
printf("%d is sum %d\n",s1,p);
printf("%d is sum %d\n",s2,d);
printf("%d is sum %d\n",s3,n);
printf("%d is sum %d\n",s4,q);
}
else
printf("Not enough change\n");
return 0;
}
c) 找换集合的元素如果是{1,3,4},被找换的元素如果是10 ,那么采用上述方法得到的找换方法是:4,4,1,1。 而最优的方式是:4,3,3。