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; }