zoukankan      html  css  js  c++  java
  • Day2-G-Sticks-POJ1011

    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

    简述:给你n个木棒及其长度,求其能组成的最短的相同长度的木棒的长度。
    分析:既然是最短搜索,用DFS+回溯即可,找出其最大的木棒长度,其可能的长度在最大长与长度和之间,与F题不同,这题需要有三点剪枝才能AC
    1.不重复访问。
    2.若长度为a的木棒不满足题意,则大于等于它的都不会满足,例如:2 2 2 2 1,若第一个2不满足,则需要直接跳过到1.
    3.因为我们将木棒降序排序,第一根(最大)必然会用上,如果第一根木棒未被用上直接剪枝退出即可
    注意考虑其只合成一根木棒的情况,代码如下:
    const int maxm = 70;
    
    int vis[maxm], n, buf[maxm], tmp, len;
    
    bool comp(int a,int b) {
        return a > b;
    }
    
    bool dfs(int cur,int pos,int t) {
        if(t == tmp)
            return true;
        if(cur == len)
            return dfs(0, 0, t + 1);
        int pre = 0;
        for (int i = pos; i < n; ++i) {
            if(!vis[i]) {  // first
                int nlen = cur + buf[i];
                if(pre != buf[i] && nlen <= len) {  // second
                    pre = buf[i];
                    vis[i] = 1;
                    if(dfs(nlen,i+1,t))
                        return true;
                    vis[i] = 0;
                    if(!pos)                  //third
                        return false;
                }
            }
        }
        return false;
    }
    
    int main() {
        while(scanf("%d",&n) && n) {
            int sum = 0;
            for(int i = 0; i < n; ++i) {
                scanf("%d", &buf[i]);
                sum += buf[i];
            }
            sort(buf, buf + n,comp);
            for (len = buf[0]; len <= sum / 2; ++len) {  // 若大于sum/2必然只能合成一根木棒
                if(sum % len)
                    continue;
                tmp = sum / len;
                memset(vis, 0, sizeof(vis));
                if(dfs(0,0,0))
                    break;
            }
            if(len > sum / 2)
                printf("%d
    ", sum);
            else
                printf("%d
    ", len);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Android内存泄漏检测利器:LeakCanary
    android webview js交互 第一节 (java和js交互)
    Android Studio JNI/NDK 编程(二) Windows 下环境搭建 demo 开发
    Android Volley 框架的使用(一)
    Android 6.0动态添加权限
    Android中使用OKHttp上传图片,从相机和相册中获取图片并剪切
    Dom对象的研究
    js 数据类型具体分析
    js 1.变量提升 2.条件语句 3.循环语句 4.加号+的使用
    js 的运算
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11222788.html
Copyright © 2011-2022 走看看