pku 1011(dfs)

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;
}
發佈了32 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章