PAT 甲级 1068 Find More Coins
这道题是给你n个硬币,要求用若干个硬币正好支付m,且这些硬币的在所有解中的序列最小。背包问题,难点在于如何保证输出的硬币序列最小。这道题给出的m的范围比较小,我们可以将所有硬币按照从小到大排序,然后用一个二维数组记录剩余需要支付的钱数和是否支付硬币的状态(记忆化搜索),最先找出来的解就是答案,因为之前已经将硬币排序。
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
int n,m;
int num[10005];
int dp[10005][105];
vector<int> ans;
bool solve(int sum,int now)
{
if(sum==0) return true;
if(now>=n) return false;
if(sum<num[now])
{
dp[now][sum]=0;
return false;
}
if(dp[now][sum]!=-1)
return dp[now][sum];
if(solve(sum-num[now],now+1))
{
ans.push_back(num[now]);
return true;
}
else
{
dp[now][sum]=0;
return solve(sum,now+1);
}
}
int main()
{
cin>>n>>m;
int kcnt=0,a;
for(int i=0;i<n;i++)
{
cin>>num[i];
}
sort(num,num+n);
memset(dp,-1,sizeof(dp));
if(!solve(m,0))
{
cout<<"No Solution";
}
else
{
sort(ans.begin(),ans.end());
cout<<ans[0];
for(int i=1;i<ans.size();i++)
cout<<' '<<ans[i];
}
return 0;
}