题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=995
动态规划问题,定义一个数组dp[i]表示i最少需要的硬币个数,假设给定的硬币面值为a,b,c,d……,
则 dp[i]=min(dp[i-a],dp[i-b],dp[i-c],dp[i-d],……)+1,(i-a,i-b,……>=0)。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int num[55],dp[100005];
void Solve(int n,int m)
{
dp[0]=0;
for(int i=1;i<=m;i++)
{
int mi(200000);
for(int j=0;num[j]<=i && j<n;j++)
{
if(mi>dp[i-num[j]] && dp[i-num[j]]!=-1)
mi=dp[i-num[j]];
}
if(mi!=200000) dp[i]=mi+1;
}
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m),m+n)
{
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
scanf("%d",&num[i]),dp[num[i]]=1;
sort(num,num+n);
Solve(n,m);
while(dp[m] == -1) //所给数据不能用硬币表示
m--;
printf("%d\n",dp[m]);
}
return 0;
}