题意:问你凑出K的所有子集C之和
思路:令dp[i][j][k]为用第i个凑出j的子集之和为k是否可行
然后dp[i][j][k]|=dp[i-1][j][k],dp[i][j][k]|=dp[i-1][j-c][k],dp[i][j][k]|=dp[i-1][j-c][k-c]直接搞就好了
注意:会爆内存,改用bool或者滚动数组就好了
#include <set> #include <map> #include <stack> #include <queue> #include <deque> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-9 #define maxn 1000100 #define MOD 1000000007 int n,m; bool dp[505][505][505]; int main() { int t; //scanf("%d",&t); while(scanf("%d%d",&n,&m) != EOF) { memset(dp,0,sizeof(dp)); dp[0][0][0] = 1; for(int i = 1; i <= n; i++) { int x; scanf("%d",&x); for(int j = 0; j <= 500; j++) for(int k = 0; k <= 500; k++) { dp[i][j][k] |= dp[i-1][j][k]; if(j >= x) dp[i][j][k] |= dp[i-1][j-x][k]; if(j >= x && k >= x) dp[i][j][k] |= dp[i-1][j-x][k-x]; } } vector<int> ans; for(int i = 0; i <= 500; i++) if(dp[n][m][i]) ans.push_back(i); printf("%d\n",ans.size()); for(int i = 0; i < ans.size(); i++) printf("%d ",ans[i]); printf("\n"); } return 0; }