• 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;
    }
  • 相关阅读:
    [No00004E]千万不要“拼命”工作——写在滴滴总裁柳青患癌症之后
    [No00004D]深度思考好文:软件工程师的困境
    [No00004C]软件工程师的创业陷阱:接私活
    [No00004B]Windows 下面为Python3.5安装NoteBook
    [No00004A]为什么你看了很多书,却依然没有洞见
    [No000049]狗日的中年——姜文
    [No000048]程序员的成长过程中,有哪些阶段?
    [No000047]好的架构源于不停地衍变,而非设计
    [No000046]为什么跳槽加薪会比内部调薪要高?
    [No000045]最好的休息,不是睡觉!
  • 原文地址:https://www.cnblogs.com/lipenglin/p/4375679.html
Copyright © 2020-2023  润新知