题干
C++实现——复杂度极高的深度优先遍历(容易超时)
#include <iostream>
#include <vector>
using namespace std;
int sum = 0;
int diff = 0;
void DFSFindMinDiff(vector<int> &arr,int pos,int sa) {
if(pos == arr.size()) {
return;
}
DFSFindMinDiff(arr,pos+1,sa);
int newdiff;
if(2*(sa+arr[pos]) - sum > 0) {
newdiff = 2*(sa+arr[pos]) - sum;
} else {
newdiff = sum - 2*(sa+arr[pos]);
}
if(newdiff < diff) {
diff = newdiff;
}
DFSFindMinDiff(arr,pos+1,sa+arr[pos]);
}
int main() {
vector<int> arr;
int i;
while(scanf("%d",&i) != EOF) {
arr.push_back(i);
}
for(int i = 0; i<arr.size(); ++i) {
sum+=arr[i];
}
diff = sum;
DFSFindMinDiff(arr,0,0);
int sa = (sum-diff)/2;
int sb = sa+diff;
printf("%d %d\n",sb,sa);
return 0;
}
C++实现——优化策略(剪枝)
- arr排序,从大到小
- 先执行加入arr[pos],再执行不加入的
- 一开始sa<sb,某个时刻sa>sb,就可以终止了
- 当diff=1时,可以提前终止
- 当arr[pos] > sum/2时,可以终止
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int sum = 0;
int diff = 0;
bool exitFlag = false;
bool compare(int lhs,int rhs){
return lhs>rhs;
}
void DFSFindMinDiff(vector<int> &arr,int pos,int sa) {
if(pos == arr.size() || exitFlag == true) {
return;
}
int newdiff;
if(2*(sa+arr[pos]) - sum > 0) {
newdiff = 2*(sa+arr[pos]) - sum;
} else {
newdiff = sum - 2*(sa+arr[pos]);
}
if(newdiff < diff) {
diff = newdiff;
if(diff == 0||diff==1||2 * arr[pos] > sum){
exitFlag = true;
}
}
if(2*(sa+arr[pos]) - sum < 0){
DFSFindMinDiff(arr,pos+1,sa+arr[pos]);
}
DFSFindMinDiff(arr,pos+1,sa);
}
int main() {
vector<int> arr;
int i;
while(scanf("%d",&i) != EOF) {
arr.push_back(i);
}
for(int i = 0; i<arr.size(); ++i) {
sum+=arr[i];
}
diff = sum;
sort(arr.begin(),arr.end(),compare);
DFSFindMinDiff(arr,0,0);
int sa = (sum-diff)/2;
int sb = sa+diff;
printf("%d %d\n",sb,sa);
return 0;
}