zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x22dfs 经典搜索剪枝 第三遍做了

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

    又是拼木棍呀,不过这次我是对他的剪枝原理完全弄清楚了,最后两条剪枝还真的是很难想到的。这次的剪枝中加入了一条:我们在某一跟木棍中拼接时,选择的木棍长度是递减的,这样就保证了搜索树中不会有重叠的部分,不过其实在木棍中,小木棒是无序的,可以用这个策略来证明剪枝的正确性,也就是说,拼第一根失败和拼最后一根失败之后,这个分支就不可能搜索到最终状态了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define maxn 100
    int a[maxn],len,cnt,n;
    int vis[maxn];
    int sum;
    int fail;//上一次拼接失败的木棍的长度 
    //last用来保证我们选择木棒的时候是按照递减的顺序选取的,防止搜索同样的状态空间 
    bool dfs(int stick,int cab,int last){//状态分别是当前在拼的是第几根木棍,当前木棍长度,开始选择的编号 
        if(stick==cnt+1)return true;
        if(cab==len)return dfs(stick+1,0,1);//新的木棍从第一根开始重新选择人拼接方案
        fail=0;
        for(int i = last; i<=n;i++){
            if(!vis[i] && cab+a[i]<=len && a[i]!=fail){//没用过并且能拼并且不是失败决策
                 vis[i]=1; 
                if(dfs(stick,cab+a[i],i+1))return true;
                fail=a[i];//记录本次拼接失败的 木棒长度 
                vis[i]=0;
                if(cab==0 || cab+a[i]==len)return false;
            }
        } 
        return false;
    }
    bool cmp(int &a,int &b){return a>b;}
    int main(){
        while(cin>>n && n){
            sum=0;
            int minlen=-0x7f7f7f7f;
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                sum+=a[i];
                minlen=max(minlen,a[i]);
            }
            sort(a+1,a+n+1,cmp);//降序,优先考虑决策少的方案
            for(int i=minlen;i<=sum;i++){
                if(sum%i)continue;
                len=i;
                cnt=sum/len;
                memset(vis,0,sizeof(vis));
                if(dfs(1,0,1))break;
            }
            cout<<len<<endl;        
        }
    } 

     

  • 相关阅读:
    Cookie数据的编码及解码
    删除单链表节点,时间复杂度为O(1)
    匹配URL
    C#文本框允许使用ctrl+A
    实现统计一个字符串所含的不同字符的总数
    调用win32 api 函数SendMessage() 实现消息直接调用
    关于C++的const对象
    从一个文本文件中找出使用频率最高的五个字符
    C++基础中的基础(深拷贝与浅拷贝)
    python+Django CRM客户关系管理系统开发(十)--左右移动选择框功能开发
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13162204.html
Copyright © 2011-2022 走看看