搜索 + 剪枝 --- POJ 1101 : Sticks

来源:互联网 发布:linux写入文件命令 编辑:程序博客网 时间:2024/05/18 02:20
 Sticks

Problem's Link:   http://poj.org/problem?id=1011

 


 

Mean: 

http://poj.org/problem?id=1011&lang=zh-CN&change=true

analyse:

爆搜,但是其中蕴含着很多剪枝。

Time complexity: O(n^2)

 

Source code: 

 

//  Memory   Time//  1347K     0MS//   by : Snarl_jsb//   2014-11-07-17.14#include<algorithm>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<vector>#include<queue>#include<stack>#include<map>#include<string>#include<climits>#include<cmath>#define N 1000010#define LL long longusing namespace std;int n,sum,len;vector<int> sti(65);vector<bool> used(sti.size());// k-----从第k根开始往后判断// total-----该回合还剩下的长度// sum----未选取的棍子的总长度bool dfs(int k,int total,int sum){    if(total==0)    {        sum-=len;        if(sum==0)        {            return true;        }        else        {            total=len;            for(k=0;used[k];++k); //找出未选的最靠前的一根            used[k]=1;            //由于从第k根开始选,第k根必选,从k+1根开始搜索            if(dfs(k+1,total-sti[k],sum))                return true;            used[k]=0;            sum+=len;        }    }    else    {        for(int i=k;i<n;++i)        {            if(sti[i]==sti[i-1]&&(!used[i-1])&&i>0)                continue;            if(total>=sti[i]&&(!used[i]))            {                total-=sti[i];                used[i]=1;                if(dfs(i,total,sum))                    return true;                total+=sti[i];                used[i]=0;                if(sti[i]==total)  //剪枝:该段的长度正好等于需要的长度,但是该方案行不通,直接返回false退出该函数                  break;            }        }    }    return false;}bool cmp(int a,int b){    return a>b;}int main(){    ios_base::sync_with_stdio(false);    cin.tie(0);//    freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin);//    freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout);    while(cin>>n,n)    {        sum=0;        int tmp;        sti.clear();        for(int i=0;i<n;++i)        {            used[i]=0;            cin>>tmp;            sum+=tmp;            sti.push_back(tmp);        }        sort(sti.begin(),sti.end(),cmp);        bool flag=false;        for(len=sti.front();len<=sum/2;++len)        {            if(sum%len==0)            {                if(dfs(0,len,sum))                {                    cout<<len<<endl;                    flag=1;                    break;                }            }        }        if(!flag)            cout<<sum<<endl;    }    return 0;}/*95 2 1 5 2 1 5 2 141 2 3 4845 56 78 456 1231 456456 45 123*/

  

 

0 0
原创粉丝点击