动态规划学习(1):最少硬币数Coin Change

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

猜你喜欢

转载自blog.csdn.net/weixin_44142774/article/details/112603898