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;
    }
  • 相关阅读:
    洛谷1052——过河(DP+状态压缩)
    mod4最优路径问题(转载)
    初次接触python,怎么样系统的自学呢?
    对AM信号FFT的matlab仿真
    初次使用自己写的testbench 验证了简单的NOT门。
    写简单的tb(testbench)文件来测试之前的FSM控制的LED
    利用简单的有限状态机(FSM)来实现一个简单的LED流水灯
    利用状态机(FSM)进行简单的uart串口发送数据
    用matlab脚本语言写M文件函数时用三种方法简单实现实现DFT(离散傅里叶变换)
    作为新手对于初次接触matlab的一些感受。
  • 原文地址:https://www.cnblogs.com/lipenglin/p/4375679.html
Copyright © 2011-2022 走看看