所以在這裏我走了,我們可以保持一個DP狀態dp[idx][sum1]
其中IDX是指當前索引數組中和SUM1是分區1的總和,使用這兩個參數,我們可以提取第三paramater那被SUM2(SUM2 = totalSum - SUM1),這將幫助我們降低了無狀態的,剩下的就是一個簡單的遞歸DP解決方案
#include<bits/stdc++.h>
using namespace std;
int n, arr[100], tot, dp[100][100000], mark[100];
int solve(int idx, int sum1){
if(idx == n){
int sum2 = tot - sum1;
//cout << sum1 << " " << sum2 << endl;
if(sum1 == sum2) return 1;return 0;
}
if(dp[idx][sum1] != -1) return dp[idx][sum1];
int v1 = 0, v2 = 0;
v1 = solve(idx+1, sum1);
v2 = solve(idx+1, sum1 + arr[idx]);
if(v1 + v2 > 0) dp[idx][sum1] = 1;
else dp[idx][sum1] = 0;
return dp[idx][sum1];
}
void check(int idx, int sum1){
if(idx == n) return;
int v1 = solve(idx+1, sum1);
int v2 = solve(idx+1, sum1 + arr[idx]);
if(v1 == 1){
mark[idx] = 1;
check(idx+1, sum1);
}else{
mark[idx] = 2;
check(idx+1, sum1 + arr[idx]);
}
}
int main(){
cin >> n;
for(int i = 0;i < n;i++) cin >> arr[i], tot += arr[i];
memset(dp, -1, sizeof dp);
int ct = solve(0, 0);
if(ct == 0){
cout << "No Partition" << endl;
}else{
check(0, 0);
for(int i = 0;i < n;i++) if(mark[i] == 1) cout << arr[i] << " ";cout << endl;
for(int i = 0;i < n;i++) if(mark[i] == 2) cout << arr[i] << " ";cout << endl;
}
}
鏈接到Ideone:https://ideone.com/6MKLK0
還記得那DP陣列定義,否索引是100,這意味着我們可以解決它100個元素,並且所有這些元素的總和不應該超過100000(這是第二個參數),如果您想增加需要更改狀態的元素數量,所有元素的總和也一樣。
這可以使用動態編程 – uSeemSurprised
如果我選擇了你的腦子有點頭腦? @u_seem_surprised –
我們可以保持dp狀態爲'dp [idx] [']來解決問題,我想我可以在C++中編寫一個遞歸dp解決方案。 – uSeemSurprised