现在的位置: 首页 > 综合 > 正文

POJ1011 Sticks

2019年02月28日 ⁄ 综合 ⁄ 共 1667字 ⁄ 字号 评论关闭
Sticks
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 105051   Accepted: 23938

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

Source

很蛋疼的题啊,刚刚看题时想到了coj的1021题,其实思路差不多,就是数据量和时间复杂度比coj1021要求高很多,呵呵,开始逐渐明白剪枝的意义了。

这里主要要注意这几点:

1将数据排序

2最终的结果肯定在最长小段和所有小段的和之间

3答案肯定是所有小段和的约数

4如过排序后相邻像个一样,而前一个没用来组成大段,那后一个也不用考虑

5如果要组成大段的第一个没能成功构成大段,那么直接退出

最后,还要注意细节就好

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int a[65],n,m,s,ok,l;
bool v[65];
bool cmp(int x,int y)
{
    return x>y;
}
bool go(int d,int len,int num)
{
    if(num==m-1)
    {
        return true;
    }
    for(int i=d; i<n; i++)
    {
        if(v[i]||(i&&v[i-1]==0&&a[i]==a[i-1]))continue;
        if(len+a[i]==l)
        {
            v[i]=1;
            if(go(0,0,num+1))return true;
            v[i]=0;
            return false;
        }
        else if(len+a[i]<l)
        {
            v[i]=1;
            if(go(i+1,len+a[i],num))return true;
            v[i]=0;
            if(len==0)return false;
        }
    }
    return false;
}
int main()
{
    while(scanf("%d",&n))
    {
        if(n==0)return 0;
        s=0;
        ok=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            s+=a[i];
        }
        sort(a,a+n,cmp);
        for(l=a[0]; l<=s; l++)
        {
            if(s%l!=0)continue;
            m=s/l;
            memset(v,0,sizeof(v));
            if(go(0,0,0))break;
        }
        printf("%d\n",l);
    }
    return 0;
}
【上篇】
【下篇】

抱歉!评论已关闭.