• poj 1011


                                                                Sticks

    Description

    George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

    Input

    The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.

    Output

    The output should contains the smallest possible length of original sticks, one per line.

    Sample Input

    9
    5 2 1 5 2 1 5 2 1
    4
    1 2 3 4
    0
    

    Sample Output

    6
    5

    解题思路:

    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* vist,int len,int InitLen,int s,int num)  //len:当前正在组合的棒长  InitLen:目标棒长
    {                                                                  //s:stick[]的搜索起点  num:已用的棒子数量
        if(num==n)
            return true;

        int sample=-1;
        for(int i=s;i<n;i++)
        {
            if(vist[i] || stick[i]==sample)  //剪枝3,等长的木棒只搜索一次
                continue;

            vist[i]=true;
            if(len+stick[i]<InitLen)
            {
                if(dfs(stick,vist,len+stick[i],InitLen,i,num+1))
                    return true;
                else
                    sample=stick[i];
            }
            else if(len+stick[i]==InitLen)
            {
                if(dfs(stick,vist,0,InitLen,0,num+1))
                    return true;
                else
                    sample=stick[i];
            }
            vist[i]=false;

            if(len==0)  //剪枝4,构建新棒时,对于新棒的第一根棒子,在搜索完所有棒子后都无法组合
                break;  //则说明该棒子无法在当前组合方式下组合,不用往下搜索(往下搜索会令该棒子被舍弃),直接返回上一层
        }
       return false;
    }

    int main(void)
    {
        while(cin>>n && n)
        {
            int* stick=new int[n];
            bool* vist=new bool[n];
            int sumlen=0;

            for(int i=0;i<n;i++)
            {
                cin>>stick[i];
                sumlen+=stick[i];
                vist[i]=false;
            }

            qsort(stick,n,sizeof(stick),cmp);
            int maxlen=stick[0];   //最大的棒为InitLen的搜索起点

            bool flag=false;
                                 //剪枝1,若能在[maxlen,sumlen-InitLen]找到最短的InitLen,该InitLen必也是[maxlen,sumlen]的最短
            for(int InitLen=maxlen;InitLen<=sumlen-InitLen;InitLen++)  //InitLen:原始棒长
            {   //剪枝2,InitLen必是sumlen的约数
                if(!(sumlen%InitLen) && dfs(stick,vist,0,InitLen,0,0))
                {
                    cout<<InitLen<<endl;
                    flag=true;
                    break;
                }
            }
            if(!flag)
                cout<<sumlen<<endl;

            delete stick;
            delete vist;
       }
        return 0;
    }

  • 相关阅读:
    MySQL链接超时的解决办法
    使用Axis开发Web Service程序
    Linux动态库(.so)搜索路径
    MYSQL性能调优简述
    什么是AXIS
    巧夺天工的kfifo
    双离合DSG
    实例讲解C# WebService
    如何为 MySQL 选择更合适的服务器硬件
    7 MySQL 事务与锁定命令
  • 原文地址:https://www.cnblogs.com/ngyifeng/p/3702993.html
Copyright © 2020-2023  润新知