给定n个硬币及面值,求从能凑成sk的硬币中,能凑成什么面值
dp[ i ][ j ][ k ] 表示前i个硬币,能凑成面值为j的硬币中,能否凑成面值k
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 500 + 5;
bool dp[2][maxn][maxn];
int v[maxn];
int main()
{
int n,sk;
scanf("%d%d",&n,&sk);
int c;
bool fg = 0;
dp[fg][0][0] = 1;
for (int i = 1; i <= n; i ++) {
scanf("%d",&c);
fg = !fg;
for (int j = 0; j <= sk; j ++) {
for (int k = 0; k <= j; k ++) {
dp[fg][j][k] |= dp[!fg][j][k];
if(j >= c){
dp[fg][j][k] |= dp[!fg][j - c][k];
if(k >= c){
dp[fg][j][k] |= dp[!fg][j - c][k - c];
}
}
}
}
}
int ans = 0;
for (int k = 0; k <= sk; k ++) {
if(dp[fg][sk][k]) {
v[ans ++] = k;
}
}
printf("%d\n",ans);
for (int i = 0; i < ans; i ++) {
printf("%d%c",v[i],i == ans - 1 ? '\n' : ' ');
}
return 0;
}