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
  • 相关阅读:
    VMware报错:无法连接 MKS: 套接字连接尝试次数太多;正在放弃
    java进阶学习计划
    js实现动态建立表格-------Day59
    Java通过POI技术操作Excel(3)----数据导出
    java通过POI技术操作Excel(2)----模板读取,录入数据
    Form表达元素美化篇----好看的搜索框(1)
    java通过POI技术操作Excel(1)----模板导出
    hibernate中 org.hibernate.MappingException: invalid configuration 报错
    中高级PHP程序员应该掌握哪些技术?
    Win10下Chrome浏览器无法安装 Adobe Flash Player 如何解决
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11222788.html
Copyright © 2011-2022 走看看