算法实验8:划分问题
http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=4807
dp[i][j]表示前i个元素形成的集合的子集的和能否为j
如果dp[i-1,j] = 1或者dp[i-1,j-a[i]] = 1,则dp[i,j] =1.
每一行都是由他的前一行得到的
注意:dp[0][0] = 1;
#include <iostream> #include <cstring> #include <cstdlib> using namespace std; int main() { int n,a[305],sum = 0,b[305]; cin >> n; for(int i = 1; i <= n; i++) { cin >> a[i]; sum += a[i]; } if(sum %2 == 1) { cout << "no" << endl; } else { int** dp = (int**)malloc(sizeof(int*)*(n+1)); for(int i = 0; i <= n; i++) { dp[i] = (int*)malloc(sizeof(int)*(sum/2+1)); } for(int i = 0; i <= n; i++) { for(int j = 0; j <= sum/2; j++) { dp[i][j] = 0; } } dp[0][0] = 1;//一定要的啊 for(int i = 1; i <= n; i++) { for(int j = 0; j <= sum/2; j++) { if(i == 1) { dp[1][0] = 1; dp[1][a[i]] = 1; } else { if(dp[i-1][j] == 1 || dp[i-1][j-a[i]] == 1) dp[i][j] = 1; } } } if(dp[n][sum/2] == 1) {// 输出划分后的数组 int k = n,t = sum/2,kk = 0; while(t != 0) { if(a[k] <= t && dp[k-1][t-a[k]]==1&&dp[k][t] == 1) { b[kk++] = a[k]; t -= a[k]; } k--; } for(int i = kk-1; i >= 0; i--) { cout << b[i]; if(i > 0) cout << " "; } cout << endl; free(dp); } else cout << "no" << endl; } return 0; }