687C
dp
以前做过 忘了。
想破脑袋不知道怎么设状态
dp[i][j][k]表示选到第i个硬币,当前和为j,能否弄出k
dp[i][j][k]|=dp[i-1][j][k]|dp[i-1][j][k-c[i]]|dp[i-1][j-c[i]][k-c[i]]
如果发现状态不行,就试着多加一维,也许就能搞定
#include<bits/stdc++.h> using namespace std; const int N = 510; int n, k, pre; int dp[2][N][N], c[N]; vector<int> ans; int main() { scanf("%d%d", &n, &k); for(int i = 1; i <= n;++i) scanf("%d", &c[i]); dp[pre][0][0] = 1; for(int x = 1; x <= n; ++x) { pre ^= 1; for(int i = 0; i <= k; ++i) for(int j = 0; j <= k; ++j) { dp[pre][i][j] = dp[pre ^ 1][i][j]; if(i - c[x] >= 0) { dp[pre][i][j] |= dp[pre ^ 1][i - c[x]][j]; if(j - c[x] >= 0) dp[pre][i][j] |= dp[pre ^ 1][i - c[x]][j - c[x]]; } } } for(int i = 0; i <= k; ++i) if(dp[pre][k][i]) ans.push_back(i); printf("%d\n", ans.size()); sort(ans.begin(), ans.end()); for(int i = 0; i < ans.size(); ++i) printf("%d ", ans[i]); return 0; }