1.先来个具体的例子题目:
2.解题步骤思想:
记f(x):付清x元需要的最少硬币数
(1)假设f(27)=k,即最少需要1 2 3 …k枚硬币,其对应的币值分别为a1 a2 a3 …ak
(2)则f(27)=f(27-ak)+1,由题知ak可能为2 5 7,故有:
f(27)=f(27-2)+1
f(27)=f(27-5)+1
f(27)=f(27-7)+1
所以f(27)=min{f(27-2)+1,f(27-5)+1,f(27-7)+1}
故f(x)=min{f(x-2)+1,f(x-5)+1,f(x-7)+1}
(3)而且我们知道f(0)=0,即最少用0枚硬币付清0元,这是初始条件。动态规划中需要写明初始条件的情况:需要某个值但是根据写的公式解不出来
(4)公式中x-2 x-5 x-7是有可能出现负数的,可以让此时的f(x)为最大值
(5)由公式可知要想知道后面的f(x)需要前面的f(x),故要从前往后算
3.具体题目:
题目分析:面值是给出的,钱的总数也是给出的,需要输出的仅是最少的硬币数目而不是具体的组成,故采用动态规划
#include<stdio.h>
#include<stdlib.h>
#define IMX 2147483647
#define min(a,b) (a<b)?a:b
int main()
{
int money[5],i,j,count=0,num;
char c;
while(scanf("%c ",&c)&&c!='\n')
{
money[count++]=c-'0';
}
scanf("%d",&num);
int f[num+1];
f[0]=0;
for(i=1;i<num+1;i++)
{
f[i]=IMX;
for(j=0;j<count;j++)
{
if(i>=money[j]&&f[i-money[j]]!=IMX)
f[i]=min(f[i-money[j]]+1,f[i]);
}
}
if(f[num]==IMX)
f[num]==-1;
printf("%d",f[num]);
return 0;
}