• POJ 1011 Sticks(搜索 && 剪枝 && 经典)


    题意 : 有n根木棍(n<=64),它们由一些相同长度的木棍切割而来,给定这n根木棍的长度,求使得原来长度可能的最小值。

    分析 : 很经典的深搜题目,我们发现答案只可能是所有木棍长度总和的因数,那么我们只要去枚举因数然后搜索是否可行即可!具体实现看代码可能更容易看懂,这里不赘述。重要的是体会此类深搜的代码构建过程以及剪枝的考虑的巧妙性!

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int maxn = 64 + 5;
    bool vis[maxn];
    int sticks[maxn];
    int CurLen;
    int n;
    int Remain;///每一次都去重置为
    bool DFS(int id, int Lack)///传入的参数为上次选择了哪个木棍、当前还缺多少才能组成一个新的目标木棍
    {
        if(Lack == 0){///已经组成一个新的木棍了,
    
            Remain -= CurLen;
            if(Remain == 0) return true;///如果当前总长为0,说明此方案可行!
    
            int which;
            for(which=0; vis[which]==true; which++);///由于是排好序,我们取第一个没有使用过的木棍开始下一次的搜索
    
            vis[which] = true;///标记
    
            if( DFS(which, CurLen-sticks[which]) ) return true;///开始新一轮搜索
    
            vis[which] = false;///记得标记回来
    
            Remain += CurLen;///赋值回来!搜索题代码应当注意的地方!
    
        }else{
            for(int i=id; i<n; i++){
                if(i>0 && (sticks[i]==sticks[i-1] && !vis[i-1])) continue;///剪枝:排序后,如果有数字不能返回true,说明在此刻选
                                                                          ///择同样的数字也是一样的结果,所以跳过
    
                if(vis[i] || Lack < sticks[i]) continue;
    
                Lack -= sticks[i];
                vis[i] = true;
    
                if( DFS(i, Lack) ) return true;
    
                Lack += sticks[i];
                vis[i] = false;
    
                if(sticks[i] == Lack) break;///剪枝:如果当前if成立,说明刚刚的DFS肯定是
                                            ///到达过Lack==0的,既然不返回true,那么说明
                                            ///此方案不行,不必继续往下面搜下去了!
            }
        }
        return false;
    }
    
    bool cmp(int fir, int sec){ return fir > sec; }
    
    int main(void)
    {
        while(~scanf("%d", &n) && n){
            int tot = 0;
    
            for(int i=0; i<n; i++){
                scanf("%d", &sticks[i]);
                tot += sticks[i];///累计总和
                vis[i] = false;
            }
    
            sort(sticks, sticks+n, cmp);///排序方便剪枝
    
            bool ok = false;
            for(int Len=sticks[0]; Len<=tot/2; Len++){
                if(tot % Len == 0){
                    Remain = tot;///将Remain重置,代表当前搜索状态下总长度还剩多少,如果为0说明成功
                    CurLen = Len;///全局变量记录当前枚举的是哪个因数,方便深搜操作
                    if(DFS(0, Len)){
                        printf("%d
    ", Len);
                        ok = true;
                        break;
                    }
                }
            }
    
            if(!ok) printf("%d
    ", tot);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Python_数据类型与变量
    啦啦啦
    Java开发环境搭建
    TCP/IP 学习 --- 4(linux网络基础api)
    TCP/IP 学习 --- 3 (流量控制和拥塞控制)
    TCP/IP 学习 --- 2
    TCP/IP 学习记录 -- 1
    多线程
    如何解析xml文件
    Redis
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/7955340.html
Copyright © 2020-2023  润新知