Question:
输入:
n,v分别代表硬币系统中的面值的种类数目和要凑的零钱的总数
之后n个数字代表硬币系统
输出:
如果可以通过该硬币系统找零,请求出最少需要的硬币个数,否则输出最好的情况下,我们还剩下多少的硬币没有找(最小值)
Solution:
经典的动态规划思想
定义状态:
DP[i]代表找i零钱需要的最少的硬币的个数,如果不能找的话,DP[i]就是-1
状态转移方程:
DP[i]=min(DP[i-count[j]])+1
PS:本题的难点在于我们如何处理不存在的情况,其实我们加上判断语句就好
Code:
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdio"
#define N 100005
using namespace std;
int count[60];
int dp[N];
int n,v;
int main()
{
while(scanf("%d%d",&n,&v)&&(n+v)!=0)
{
for(int i=1;i<=n;i++)
{
cin>>count[i];
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=v;i++)
{
int temp=99999999;
for(int j=1;j<=n;j++)
{
if(i-count[j]>= 0&&dp[i-count[j]]!=-1)
temp=min(temp,dp[i-count[j]]);
}
if(temp!=99999999) dp[i]=temp+1;
else dp[i]=-1;
}
int i=v;
while(dp[i]==-1&&i>1) i--;
if(i==1) cout<<n<<endl;
else cout<<dp[i]<<endl;
}
return 0;
}