L3001 凑零钱 (30 分)

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;
}
原文地址:https://www.cnblogs.com/LengYun/p/14688736.html