华师一附中OI组
标题:
P1120 小木棍 [数据加强版]
[打印本页]
作者:
倚窗倾听风吹雨
时间:
2018-10-5 12:04
标题:
P1120 小木棍 [数据加强版]
https://www.luogu.org/problemnew/show/P1120
题目描述
乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050。
现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。
给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。
输入输出格式
输入格式:
共二行。
第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65
(管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!)
第二行为N个用空个隔开的正整数,表示N根小木棍的长度。
输出格式:
一个数,表示要求的原始木棍的最小可能长度
输入输出样例
输入样例#1:
9
5 2 1 5 2 1 5 2 1
输出样例#1:
6
说明
2017/08/05
数据时限修改:
-#17 #20 #22 #27 四组数据时限500ms500ms
-#21 #24 #28 #29 #30五组数据时限1000ms1000ms
其他时限改为200ms200ms(请放心食用)
作者:
倚窗倾听风吹雨
时间:
2018-10-5 12:04
#include<iostream>
#include<cstdlib>
#define FOR(i,a,b) for(register int i=a;i<=b;i++)
#define ROF(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;
const int N=70;
int n,l[N],len,temp,minn=0x7fff,maxn;
void dfs(int e,int sum,int res,int p)
{
if(!res)
{
cout<<e<<endl;
exit(0);
}
if(sum==e)
{
dfs(e,0,res-1,maxn);
return;
}
ROF(i,p,minn)
{
if(l[i] && i+sum<=e)
{
l[i]--;
dfs(e,sum+i,res,i);
l[i]++;
if(sum==0 || sum + i==e)break;
}
}
return;
}
int main()
{
cin>>n;
FOR(i,1,n)
{
cin>>temp;
if(temp>50)continue;
l[temp]++;len+=temp;
minn=min(minn,temp);
maxn=max(maxn,temp);
}
temp=len>>1;
FOR(i,maxn,temp)
if(len%i==0)dfs(i,0,len/i,maxn);
cout<<len<<endl;
return 0;
}
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2