码迷,mamicode.com
首页 > 其他好文 > 详细

POJ-1011-Sticks-DFS(深搜)+四次剪枝

时间:2015-07-22 14:50:25      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:dfs深搜   剪枝   poj1011   

题目链接:http://poj.org/problem?id=1011

这个题目很经典,剪枝很巧妙,可以好好的研究一下,多做几次,很有价值;

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define LL long long
using namespace std;
/*
    枚举搜索,考察剪枝的使用,难度不低;
*/
vector<int>Length;      //  动态数组;
int L,N,LastStart;
int vis[1005];          //  标记变量;
int totalLength;        //  所有棍子总长度;
bool dfs(int R,int M)
{
    if(R==0&&M==0) return true;     //  说明刚好拼成几个完全一样的棍子
    if(M==0) M=L;       //  拼完成一根,开始拼下一根;
    int NowStart=0;     //  剪枝4,从上一个棍子接着考虑的开始;从长木棍开始往下放;
    if(M!=L) NowStart=LastStart+1;
    for(int i=NowStart;i<N;i++){
        if(!vis[i]&&Length[i]<=M){      //  当可以用这根棍子的时候;
            if(i>0) if(!vis[i-1]&&Length[i]==Length[i-1]) continue; //  剪枝1,在排好序的前提下,如果上一根和这个相同,且上一根不可用,那么显然这根也不可用;
            vis[i]=1;LastStart=i;
            if(dfs(R-1,M-Length[i])) return true;       //  继续搜索;
            else{
                vis[i]=0;
                if(Length[i]==M||M==L) return false;    //  剪枝3,最后一根木棍等于这个长度,但是放失败了,那么其他棍子也是放不了替换也就没有什么意义了;
                                                        //  剪枝2,一根棍子都没有放,但是已经有一个棍子被考虑了,说明就不可能用完所有的棍子;
            }
        }
    }
    return false;
}
int main()
{
    while(~scanf("%d",&N)){
        if(!N) break;
        Length.clear();
        totalLength=0;
        for(int i=0;i<N;i++){
            int a;
            scanf("%d",&a);
            Length.push_back(a);
            totalLength+=Length[i];
        }
        sort(Length.begin(),Length.end(),greater<int>());   //  长度由长到短排序;
        for(L=Length[0];L<=totalLength/2;L++){              //  所有可能的长度枚举;
            if(totalLength%L) continue;                     //  说明不能拼成完整的这样长度的几根棍子;
            memset(vis,0,sizeof(vis));
            if(dfs(N,L)){
                printf("%d\n",L);
                break;
            }
        }
        if(L>totalLength/2) printf("%d\n",totalLength);     //  说明只能拼成一个这样的棍子;
    }
    return 0;
}


 

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ-1011-Sticks-DFS(深搜)+四次剪枝

标签:dfs深搜   剪枝   poj1011   

原文地址:http://blog.csdn.net/wlxsq/article/details/47001117

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!