
乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。
题目
- 原题地址:小木棍
- 题目编号:NC50243
- 题目类型:搜索剪枝、BFS
- 时间限制:C/C++ 1秒,其他语言2秒
- 空间限制:C/C++ 32768K,其他语言65536K
1.题目大意
n根木棍,由k根长度为l且相同的长棍截取而成,求原木棍的最小长度
2.题目分析
- 从以下几个方面考虑剪枝:
- 总长
sum会被原长l整除
- 原长一定长于截取后的木棍的最大长度
- 。。。?
3.题目代码
#include <bits/stdc++.h>
using namespace std;
int a[61], vis[61], sum, n;
bool dfs(int num,int len,int r,int j){
if(!num&&!r) return true;
if(!r&&num>0) j=0, r=len;
for(int i=j;i<n;i++){
if(a[i]<=r&&!vis[i]){
vis[i] = 1;
if(dfs(num-1,len,r-a[i],i+1)) return true;
vis[i] = 0;
if(a[i]==r||r==len) break;
while(a[i]==a[i+1]) i++;
}
}return false;
}
int main() {
cin >> n;
for(int i=0;i<n;i++) cin >> a[i], sum+=a[i];
sort(a,a+n),reverse(a,a+n);
for(int i=a[0];i<=sum;i++){
if(!(sum%i)&&dfs(n,i,i,0)){cout << i << endl;break;}
}
}