L3-001 凑零钱 (30 分)
韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有 \(10^{4}\) 枚来自各个星球的硬币,需要请你帮她盘算一下,是否可能精确凑出要付的款额。
输入格式:
输入第一行给出两个正整数:\(N \; (\leq 10^{4})\) 是硬币的总个数,\(M \; (\leq 10^{2})\) 是韩梅梅要付的款额。第二行给出 \(N\) 枚硬币的正整数面值。数字间以空格分隔。
输出格式:
在一行中输出硬币的面值 \(V_{1} \leq V_{2} \leq \cdots \leq v_{k}\),满足条件 \(V_{1}+V_{2}+\cdots+v_{k}=M\)。数字间以 1 个空格分隔,行首尾不得有多余空格。若解不唯一,则输出最小序列。若无解,则输出 No Solution
。
注:我们说序列 \(\{A[1],A[2],\cdots \}\) 比 \(\{B[1],B[2],\cdots \}\)“小”,是指存在 \(k \geq 1\) 使得 \(A[i]=B[i]\) 对所有 \(i \lt k\) 成立,并且 \(A[k]<B[k]\)。
输入样例1:
8 9
5 9 8 7 2 3 4 1
输出样例1:
1 3 5
输入样例2:
4 8
7 2 4 3
输出样例2:
No Solution
参考代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,dp[105],w[10005],ans[10005],cnt;
bool ch[10005][105],flag;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>w[i];
sort(w+1,w+n+1,greater<int>());
for(int i=1;i<=n;i++)
for(int j=m;j>=w[i];j--)
if(dp[j]<=dp[j-w[i]]+w[i])
{
dp[j]=dp[j-w[i]]+w[i];
ch[i][j]=1;
}
if(dp[m]<m)return cout<<"No Solution",0;
for(int i=n;i>=1&&m;i--)
{
if(ch[i][m])
{
if(flag)cout<<' ';
cout<<w[i];
m-=w[i];
flag=1;
}
}
return 0;
}