dfs题目 有点麻烦啊 先写了一次wrong answer了
参考了一下discuss
错在了这种类型的数据上
10
21 14 13 11 9 6 4 3 2 1
正确的匹配应该是: 21 14 4 3 13 6 2 11 9 1
分析了一下应该是 在确定长度为21 是否满足条件时我是这么搜的
21
14 6 1
13 4 3 这里无法满足条件后就直接判断长度21 不行了
然后重新写过剪枝不够高明 TLE一次
参考了下discuss里别人的代码总算是改好了 32MS AC
#include <stdio.h> #include <cstdlib> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> using namespace std; int num[80]; int sum; int n; bool pan[80]; int len; int main(int argc, char *argv[]) { bool dfs(int sum, int rest, int i, int w); while (cin >> n && n) { int i(0); sum = 0; while (i < n) { cin >> num[i]; sum += num[i]; ++i; } sort(num, num + n, greater<int>()); //进行降序排列 len = num[0]; while (1) { if (sum % len) { //满足条件的长度必然是总长度的约数 ++len; continue; } memset(pan, 0, sizeof (pan)); // cout << "len=" << len << endl; if (dfs(sum, len, 0, 0)) { cout << len << endl; break; } ++len; } } return EXIT_SUCCESS; } bool dfs(int total, int rest, int i, int w) { int wrong=0; //这里是针对重复数据的,比如判断某数不符合条件后,若后面一个数与它一样,则不用继续搜索判断了 if (total == 0) return true; if (rest == 0) { return dfs(total - len, len, i + 1, 0); } int j(w); while (j < n) { if (!pan[j]) { if (pan[j] <= rest) { if(num[j]==wrong) {++j;continue;} pan[j] = 1; if (dfs(total, rest - num[j], i, j + 1) ) return true; wrong=num[j]; pan[j] = 0; } if(w==0) break; //这个剪枝非常巧妙,很难想到 } ++j; } return false; }