zoukankan      html  css  js  c++  java
  • poj1011 Sticks (搜索经典好题)

    poj1011 Sticks

    题目连接:

    poj1011

    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

    Hint

    题意

    给定n根木棒,要求将它们拼成若干根等长的木棒,问拼成的木棒最短长度。

    题解:

    dfs+剪枝。

    将木棒从长到短排序,枚举能拼成的长度搜索,枚举范围是最长木棒的长度到所有木棒总长度中能被总长度整除的部分。

    搜索:从最长的木棒开始搜,每搜到一根组合好的木棒变换搜索状态,继续从最长的开始搜,直到用完所有木棒。

    剪枝:

    1.当某根木棒无法完成组合,则无解,直接结束此次搜索,回溯到上一步;

    2.当某个长度的木棒不能再此次搜索中使用,则跳过所有该长度木棒的搜索。

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 66;
    int n, sum, len, a[maxn];
    bool flag, vis[maxn];
    int step=0;
    
    bool cmp(int a, int b)
    {
        return a>b;
    }
    
    bool dfs(int x, int nowlen, int alllen)
    {
        if(alllen==sum)//已经用完所有木棒,正解
        {
            return true;
        }
        if(nowlen==len)//已经拼好一根木棒,继续拼下一根,并从剩下木棒中最长的木棒开始
            nowlen=0, x=1;
        for(int i=x; i<=n; ++i)
        {
            if(vis[i] || nowlen+a[i]>len)//木棒已经用过,木棒无法完成组合
                continue;
            vis[i]=true;
            if(dfs(i, nowlen+a[i], alllen+a[i]))//若此次搜索到正确结过则跳出
            {
                return true;
            }
            vis[i]=false;
            if(nowlen+a[i]==len || nowlen==0)//使用第i根木棒的情况下得不到正解,即第i根木棒无法组合成目标长度,跳出
                return false;
            while(a[i+1]==a[i]) ++i;//第i根木棒无法使用,则与第i根木棒长度相等的均无法使用
        }
        return false;
    }
    
    int main()
    {
        while(scanf("%d", &n)!=EOF && n!=0)
        {
            sum=0;
            for(int i=1; i<=n; ++i)
            {
                scanf("%d", &a[i]);
                sum+=a[i];
            }
            sort(a+1, a+n+1, cmp);
            for(len=a[1]; len<=sum; ++len)
            {
                if(sum%len==0)
                {
                    //cout<<len<<"..."<<endl;
                    memset(vis, false, sizeof(vis));
                    if(dfs(1, 0, 0))
                    {
                        printf("%d
    ", len);
                        break;
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    The Brain vs Deep Learning Part I: Computational Complexity — Or Why the Singularity Is Nowhere Near
    unity3d NGUI多场景共用界面制作
    python第三方库系列之十九--python測试使用的mock库
    oracle之单行函数
    Andropid自己定义组件-坐标具体解释
    [WebGL入门]二,開始WebGL之前,先了解一下canvas
    【BZOJ2318】【spoj4060】game with probability Problem 概率DP
    苹果改版之后,关于隐私协议加入的问题解决方式
    Binary Tree Level Order Traversal II
    首届中国智慧城市协同创新峰会将于6月20日在大连隆重举行
  • 原文地址:https://www.cnblogs.com/xiepingfu/p/7265686.html
Copyright © 2011-2022 走看看