链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805402305150976
题解
先对所有的硬币升序排序,然后
d
p
dp
dp
f
i
j
f_{ij}
fij表示从第
i
i
i硬币开始的硬币到最后一个硬币能否组成
j
j
j这么大的面值
最后贪心输出一下就好了
代码
#include <bits/stdc++.h>
#define iinf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3fll
#define ll long long
#define maxn 100010
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
ll f[10010][110], a[maxn], N, M;
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
void init()
{
ll i;
N = read(), M = read();
for(i=0;i<N;i++)a[i] = read();
sort(a,a+N);
}
void dp()
{
ll i, j;
f[N][0]=1;
for(i=N-1;i>=0;i--)
{
for(j=0;j<=M;j++)f[i][j]=f[i+1][j];
for(j=0;a[i]+j<=M;j++)f[i][j+a[i]]|=f[i+1][j];
}
}
void print()
{
ll i, res=M;
for(i=0;i<N;i++)
{
if(a[i]>res)break;
if(f[i+1][res-a[i]])
{
printf("%lld",a[i]);
if(res!=a[i])putchar(32);
res-=a[i];
}
}
if(res)printf("No Solution");
}
int main()
{
init();
dp();
print();
return 0;
}