zoukankan      html  css  js  c++  java
  • poj1011 搜索+剪枝

    DFS+剪枝 POJ2362的强化版,重点在于剪枝 令InitLen为所求的最短原始棒长,maxlen为给定的棒子堆中最长的棒子,sumlen为这堆棒子的长度之和,那么InitLen必定在范围[maxlen,sumlen]中 根据棒子的灵活度(棒子越长,灵活度越低) DFS前先对所有棒子降序排序 剪枝: 1、 由于所有原始棒子等长,那么必有sumlen%Initlen==0; 2、 若能在[maxlen,sumlen-InitLen]找到最短的InitLen,该InitLen必也是[maxlen,sumlen]的最短;若不能在[maxlen,sumlen-InitLen]找到最短的InitLen,则必有InitLen=sumlen; 3、 由于所有棒子已降序排序,在DFS时,若某根棒子不合适,则跳过其后面所有与它等长的棒子; 4、 最重要的剪枝:对于某个目标InitLen,在每次构建新的长度为InitLen的原始棒时,检查新棒的第一根stick[i],若在搜索完所有stick[]后都无法组合,则说明stick[i]无法在当前组合方式下组合,不用往下搜索(往下搜索会令stick[i]被舍弃),直接返回上一层 

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int cmp( const void* a, const void* b )
    {
        return *( int* )b - *( int* )a;
    }
    
    int n;
    bool dfs( int* stick, bool* visit, int len, int InitLen, int s, int num )
    {
        if ( num == n )
            return true;
    
        int sample = -1;
        for( int i = s; i<n; i++ )
        {
            if( visit [i] || stick[i] == sample )
                continue;
            visit[i] = true;
            if( len + stick[i] < InitLen )
            {
                if( dfs( stick, visit, len+stick[i], InitLen, i, num+1))
                    return true;
                else
                    sample = stick[i];
            }
            else if( len + stick[i] == InitLen )
            {
                if( dfs( stick, visit, 0, InitLen, 0, num+1 ))
                    return true;
                else sample = stick[i];
            }
            visit[i] = false;
    
            if( len == 0 )
                break;
    
        }
        return false;
    }
    
    int main()
    {
        while( cin >> n && n )
        {
            int* stick = new int[n];
            bool* visit = new bool[n];
            int sumlen = 0;
            int i;
            for( i = 0; i<n; i++ )
            {
                cin >> stick[i];
                sumlen+=stick[i];
                visit[i] = false;
            }
    
            qsort( stick, n, sizeof(stick), cmp );
            int  maxlen = stick[0];
    
            bool flag = false;
    
            for ( int InitLen = maxlen;InitLen <= sumlen - InitLen; InitLen++)
            {
                if( !( sumlen%InitLen) && dfs( stick, visit, 0, InitLen, 0, 0 ))
                {
    
                    cout<< InitLen <<endl;
                    flag = true;
                    break;
                }
            }
            if( !flag )
                cout<< sumlen << endl;
    
            delete stick;
            delete visit;
        }
        return 0;
    }
  • 相关阅读:
    聊聊微服务的服务注册与发现
    consui(二)集群配置
    centos7 yum安装遇到报错:Head V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEYer
    smartsvn9破解及license文件
    no matching function for call to 'make_pair(std::string&, size_t&)'
    Linux cmp命令——比较二进制文件(转)
    深入探讨Linux静态库与动态库的详解(转)
    Linux下的编译器(转)
    Linux中more和less命令用法(转)
    Linux环境下GNU, GCC, G++编译器(转)
  • 原文地址:https://www.cnblogs.com/lipenglin/p/4375679.html
Copyright © 2011-2022 走看看