• 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
  • 相关阅读:
    uvm_cookbook--sequences--wait for a signal
    Makefile目标文件搜索(VPATH和vpath
    git stash
    vuex-persist,解决vuex中的数据刷新页面之后丢失的问题
    element表格中的输入框有时会存在输入不上的情况
    简单 Linux 文件系统?
    Shell 脚本是什么?
    什么是BASH?
    如何规划一台 Linux 主机,步骤是怎样?
    什么是GUI?
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11222788.html
Copyright © 2020-2023  润新知