POJ 1011 Sticks

来源:互联网 发布:linux常用网络命令大全 编辑:程序博客网 时间:2024/05/19 03:19

毫无疑问,非常经典的搜索题。除了在搜索前要对木棍进行排序外,在搜索过程中的两个关键的剪枝必须要考虑到,否则就TLE了:

(1)在当前尚未组合的木棍里面,先把第一条尚未组合的木棍做为原始木棍的一部分,然后尝试搜索填充这条原始木棍的剩余部分,若失败,则直接返回上一层。

(2)若当前木棍参与当前的组合方式不能得到合法的解,那么后面的长度和这条木棍相同的木棍可以直接跳过。

#include <iostream>#include <vector>#include <algorithm>using namespace std;vector<int> sticks;vector<bool> flags;int sumLen ;int len;bool Comp(int left, int second){    return left > second;}bool Dfs(bool first, int b, int l, int n){    if( n == 1 )return true;    int i = b;    while( i < sticks.size() )    {if(!flags[i] && l >= sticks[i]){    flags[i] = true;    bool ans = (l == sticks[i])?Dfs(true, 0, len, n-1): \       Dfs(false, i+1, l-sticks[i], n);    if( ans )return true;    flags[i] = false;    if( first )return false;//剪枝(1)    while(sticks[i] == sticks[i+1])//剪枝(2)++i;}++i;    }    return false;}int main(){    int num;    while( cin >> num && num )    {sticks.clear();sumLen = 0;int maxLen = 0;for(int i = 0; i < num; ++i){    int temp;    cin >> temp;    if( maxLen < temp )maxLen = temp;    sumLen += temp;    sticks.push_back(temp);}sort(sticks.begin(), sticks.end(), Comp);flags.assign(sticks.size(), false);len = maxLen ;while( len <= sumLen ){    flags.assign(sticks.size(), false);    if( !(sumLen%len) && Dfs(true, 0, len, sumLen/len) )    {cout << len << endl;break;    }    ++len;}    }    return 0;}bool Dfs(int b, int l, int n){    if( n == 1 )return true;       if( !l )    {int i = 0;while( flags[i] )    ++i;flags[i] = true;bool ans = Dfs(i+1, len-sticks[i], n-1);if( ans )    return true;flags[i] = false;return false;    }    int i = b;    while( i < sticks.size() )    {if(!flags[i] && l >= sticks[i]){    flags[i] = true;    bool ans = Dfs(i+1, l-sticks[i], n);    if( ans )return true;    flags[i] = false;    while(sticks[i] == sticks[i+1])++i;    /*    flags[i] = true;    if(l == sticks[i])    {int j = 0;while( flags[j] )    ++j;flags[j] = true;if( Dfs(j+1, len-sticks[j], n-1) ){    return true;}flags[j] = false;flags[i] = false;return false;    }    else     {bool ans = Dfs(i+1, l-sticks[i], n);if( ans )    return true;flags[i] = false;while(sticks[i] == sticks[i+1])    ++i;    }    */}++i;    }    return false;}