POJ1011 (深搜+剪枝)

Posted newstartcy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1011 (深搜+剪枝)相关的知识,希望对你有一定的参考价值。

技术图片
#include<iostream>//深搜学习(经典)
#include<cstdio>//深搜可以作为面临多种选择时的不断尝试
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 105;
int arr[maxn];//储存木棒长度
bool vis[maxn];//木棒是否被使用了
int n;//有n个数
bool cmp(const int a,const int b)

    return a > b;
//由大到小排列(因为合并后的木棒肯定是比最长的木棒长)   相当于小剪枝
int cnt,num;//cnt为木棒最小 num为合并后的木棒数
bool dfs(int k,int cur,int c_num)//从第k根木棒开始尝试,当前合并的木棒长为cur,c_num为已经整理好的木棒数

    if(c_num==num)
        return true;//说明已经完成
    if(cur==cnt)
        return dfs(0,0,c_num+1);//重新更新
    int i,prev = 0;//剪枝 eg 5 5 2 1 如果5不能,同理后一个5也不能完成
    for(i=k;i!=n;++i)
    
        if(!vis[i]&&arr[i]+cur<=cnt&&prev!=arr[i])//剪枝    未被访问
        
            prev = arr[i];
            vis[i] = true;
            if(dfs(i+1,cur+arr[i],c_num))
                break;//如果满足条件
            vis[i] = false;//回溯
            if(k==0)//剪枝
                return false;//剪枝
        
    
    if(i!=n)
        return true;
    else
        return false;

int main()

    ios::sync_with_stdio(false);
    while(cin>>n&&n)
    
        int sum = 0;//总的长度
        for(int i=0;i!=n;++i)
        
            cin>>arr[i];//输入木棒对应长度
            sum += arr[i];
        
        sort(arr,arr+n,cmp);
        //sum / 2是有可能俩木棒合并为一根
        //cout<<sum/2<<endl;
        for(cnt = arr[0];cnt<=sum/2;++cnt)
        
            if(sum % cnt)
                continue;//cnt必定是为sum的因数的
            num = sum /cnt;//木棒的根数
            memset(vis,false,sizeof(vis));//每次尝试时更新
            if(dfs(0,0,0))
                break;//找到合适的长度
        
        if(cnt>sum/2)
            cout<<sum<<endl;
        else
            cout<<cnt<<endl;
    
View Code

 

以上是关于POJ1011 (深搜+剪枝)的主要内容,如果未能解决你的问题,请参考以下文章

poj1190 生日蛋糕(深搜+剪枝)

深搜+剪枝--poj2676--数独

poj1011(DFS+剪枝)

POJ 1011 Sticks DFS 剪枝

POJ1011 SticksDFS+剪枝

POJ 1011 Sticks