Sticks UVA-307

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 file contains blocks of 2 lines. The first line contains the number of sticks parts after cutting.
The second line contains the lengths of those parts separated by the space. The last line of the file
contains ‘0’.
Output
The output file 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,第二行有n个数,这n个数最初是有未知根木棒切割而成,现在把这些木棒拼接在一起,拼成长度相同的木棒,输出最短长度。

思路: 拼成的木棒长度一定在序列中的最大值和所有木棒长度之和,那么对这个区间中的每个数进行便利,求出能拼接的最短长度。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[100],n,m,ans;
int maxx,minn;
bool flag;
void dfs(int x,int s,int len,int st)//需要找的个数  拼接之和   需要找多少根   最大值
{
    if(!x)//找完了
    {
        ans=len;
        flag=true;
    }
    if(flag)
        return;
    if(s==len)//找到一根木棒
    {
        dfs(x-1,0,len,maxx);
        return;
    }
    for(int i=st;i>=minn;i--)
    {
        if(a[i]&&s+i<=len)
        {
            a[i]--;
            dfs(x,s+i,len,i);
            a[i]++;
            if(!s)
                break;
        }
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        int sum=0;
        memset(a,0,sizeof(a));
        maxx=0,minn=1000,flag=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            if(x>50)
                continue;
            a[x]++;//出现过几次
            sum+=x;
            if(x>maxx)
                maxx=x;
            if(x<minn)
                minn=x;
        }
        for(int i=maxx;i<=sum;i++)//对序列中的最大值和所有值之和中的每个数进行便利,找到所需木棒的最短长度
        {
            if(sum%i==0)
                dfs(sum/i,0,i,maxx);//需要找长度为i的木棒sum/i根   当前为止拼接的木棒长度    需要拼接长度为i的木棒   拼接区间 
            if(flag)
                break;
        }
        printf("%d\n",ans);
    }
    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值