POJ1011 搜索+剪枝【很好】

来源:互联网 发布:淘宝客服服务回复 编辑:程序博客网 时间:2024/05/22 11:34

1 题意。

2 分析。

枚举可能的最小长度,再搜索+剪枝,判断一下该最小长度是否可以由题目所给的一组子木条长度组合而成。

剪枝点:。。。

#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;//const int INF=0x3f3f3f3f;const int maxn=70;int stick[maxn];int visted[maxn];int len_min;int sum;int flag;int k;void Dfs(int cur_len){    int last=0;    for(int i=k;i>=1;i--){        if(!visted[i]&&(len_min-cur_len)>=stick[i]&&stick[i]!=last){ //①            visted[i]=1;            sum-=stick[i];            if(sum==0){                flag=1;                return ;            }            cur_len+=stick[i];            int temp_cur_len=cur_len;            if(cur_len==len_min){                temp_cur_len=0;            }            Dfs(temp_cur_len);            visted[i]=0;            sum+=stick[i];            cur_len-=stick[i];            if(flag) return ;            if(!flag&&cur_len==0) return;//构建的每根原始棒的第一节不匹配则不要越过这一节处理下面的,直接返回上一层  //②            if(!flag) last=stick[i];      //①        }    }    return ;}int main(){    while(~scanf("%d",&k)&&k){        sum=0;        flag=0;        for(int i=1;i<=k;i++){            scanf("%d",&stick[i]);            sum+=stick[i];            visted[i]=0;        }        sort(stick+1,stick+1+k);          //③        //cout<<stick[1]<<" "<<stick[k]<<endl;        for(int i=stick[k];i<=sum-i;i++){ //④            if( (sum-i)%i==0 ){                len_min=i;                int cur_len=0;                Dfs(cur_len);                if(flag) break;            }        }        if(!flag) cout<<sum<<endl;        else cout<<len_min<<endl;    }    return 0;}



0 0
原创粉丝点击