codevs 3498 小木棍

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
 
 
 
题目描述 Description

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过100。

    现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

    给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

 

输入描述 Input Description

输入文件共有二行。

    第一行为一个单独的整数N表示看过以后的小木柜的总数,其中N≤60,第二行为N个用空个隔开的正整数,表示N跟小木棍的长度。

 

输出描述 Output Description

输出文件仅一行,表示要求的原始木棍的最小可能长度。

样例输入 Sample Input

5 2 1 5 2 1 5 2 1

 

样例输出 Sample Output

6

数据范围及提示 Data Size & Hint

N<=60

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 62
using namespace std;
int a[MAXN],vis[MAXN];
int n,num,sum;
void dfs(int x,int aum,int k,int fr){
    if(k==x)    k=0;
    if(sum-aum==0){ cout<<x<<endl; exit(0); }
    if(sum-aum<x&&k==0||sum-aum<a[n])    return ;
    for(int i=fr;i<=n;i++){
        if(!vis[i]&&k+a[i]<x){
            vis[i]=1;
            dfs(x,aum+a[i],k+a[i],i+1);
            vis[i]=0;
        }
        else if(!vis[i]&&k+a[i]==x){
            vis[i]=1;
            dfs(x,aum+a[i],k+a[i],1);
            vis[i]=0;
        }
    }
        
}
int cmp(int a,int b){
    return a>b;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];num=max(num,a[i]);
    }
    sort(a+1,a+1+n,cmp);
    for(int i=num;i<=sum;i++)
        if(sum%i==0)
            dfs(i,0,0,1);
}
/*
7 
63 2 44 12 60 35 60 
*/
80
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 62
using namespace std;
int a[MAXN],f[MAXN];
int n,num,sum;
bool dfs(int now,int s){
    if(s<0)    return 0;
    f[now]=0;
    if(s==0)    return 1;
    for(int i=now-1;i>=1;i--)
        if(f[i]&&dfs(i,s-a[i]))    return 1;
    f[now]=1;
    return 0;
}
bool check(int x,int tot){
    memset(f,1,sizeof(f));
    for(int i=1;i<=tot;i++)
        if(!dfs(n+1,x))    return 0;
    return 1;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];num=max(num,a[i]);
    }
    sort(a+1,a+1+n);
    for(int i=num;i<=sum;i++)
        if(sum%i==0&&check(i,sum/i)){
            cout<<i<<endl;
            return 0;
        }
}
/*
7 
63 2 44 12 60 35 60 
*/

 

posted @ 2018-10-14 21:21  一蓑烟雨任生平  阅读(192)  评论(0编辑  收藏  举报