您的位置:首页 > 其它

POJ 1101 深搜的剪枝

2018-02-04 19:08 253 查看
题目描述:

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


#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std ;
const int Max = 4097 ;
int n , weight[Max] , sum ;
int package[Max] , top ;
int book[Max] ;

int DFS( int stick , int res , int i ){
if( res == 0 && stick == n ) // package[i] 时恰好全部用完,返回 1
return 1 ;
if( res == 0 ) // 刚组合了一个 package[i] , 但是还有棍子还用过,重置继续组合
res = package[i] ;
for( int j = n ; j >= 1 ; --j )
if( res >= weight[j] && book[j] == 0 ){
if( j != n && book[j+1] == 0 && weight[j] == weight[j+1] ) // 相同大小的棍子不用重复搜索
continue ;
book[j] = 1 ;
if( DFS( stick+1 , res-weight[j] , i ) )
return 1 ;
else{
book[j] = 0 ; // 回溯,这根棍子无解
if( res == package[i] || weight[j] == res ) // 如果根本选,得不到组合;刚才选的就是剩下的,却也无解
return 0 ;
}
}
return 0 ;
}

int main(){
while( cin >> n && n ){
sum = 0 ;
for( int i = 1 ; i <= n ; ++i ){
cin >> weight[i] ;
sum += weight[i] ;
}
sort( weight+1 , weight+n+1 ) ; // 让小的可以有更多组合
if( weight
> sum >> 1 ){ // 如果最大的棍子比总和的一般还要大,就只有一根了
cout << sum << endl ;
continue ;
}
top = 0 ;
for( int i = weight
; i <= sum ; ++i )
if( sum % i == 0 )
package[++top] = i ; // package 数组保存因子,因为要恰好组合,n 肯定是 i 的倍数
for( int i = 1 ; i <= top ; ++i ){
memset( book , 0 , sizeof( book ) ) ;
if( DFS( 0 , package[i] , i ) ){
cout << package[i] << endl ;
break ;
}
}
}
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: