Codeforces Round #360 (Div. 2) E. The Values You Can Make DP
E. The Values You Can Make
链接:
http://codeforces.com/contest/688/problem/E
题意:
给你n个数和k。
问n个数所有能构成k的子集合中所有的可能的和是多少?
题解:
二维dp, dp[i][j]表示当前和是i 能否构成j。
如果dp[i][j]是可以的话,那么dp[i+m][j]和dp[i+m][j+m]都是可以得!(因为是子集合!!)
最后枚举dp[K][i],把可以得放入ans数组或者vector输出即可!
代码:
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 5 const int maxn = 5e2 + 7; 6 int dp[maxn][maxn]; 7 8 int main() 9 { 10 int n, K; 11 cin >> n >> K; 12 dp[0][0] = 1; 13 for (int i = 1; i <= n; i++) { 14 int c; 15 cin >> c; 16 for (int j = K; j >= c; j--) 17 for (int k = 0; k + c <= K; k++) 18 if (dp[j - c][k]) 19 dp[j][k] = dp[j][k + c] = 1; 20 } 21 vector<int> ans; 22 for (int i = 0; i <= K; i++) 23 if (dp[K][i]) 24 ans.push_back(i); 25 cout << ans.size() << endl; 26 for (int i = 0; i < ans.size() - 1; i++) 27 cout << ans[i] << " "; 28 cout << ans[ans.size() - 1] << endl; 29 return 0; 30 }