您的位置:首页 > 其它

poj 1011 Sticks 减枝搜索

2013-04-01 17:13 232 查看
题意

  有N根棍子,分别有长度。问将其拼接成X根,长度相同,求最小长度。

解法

  搜索。

  1.因为总共n根棍子,最多拼接成n根相同长度, 并且,组成的棍子数量越多,则长度则越小

  2.拼接的棍子数量必定能够 被 \sum{stick_i} 整除

  3.若当前棍子长度 stick_i 不能够匹配, 在 stick_i = left_len 或者 stick_i = target_len 情况下, 此

长度无合法方案, 因为每一根棍子都将被使用,若有一根不能被使用,则此长度方案必定不能成立.

View Code

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define MAX(a,b) (a)>(b)?(a):(b)
int a[110], n;
bool vis[110];

bool dfs( int use, int left, int A ){
if( use == 0 && left == 0 ) return true;
if( left == 0 ) left = A;
for(int i = 0; i < n; i++){
if( vis[i] ) continue;
if( a[i] > left ) continue;
vis[i] = 1;
if( dfs( use-1, left-a[i], A ) )
return true;
vis[i] = 0;
// use a[i] is failure
if( a[i] == left || left == A )
break;
}
return false;
}
int compare( int a, int b ){
return a > b;
}
int main(){

while( scanf("%d", &n), n ){
int sum = 0;
for(int i = 0; i < n; i++){
scanf("%d", &a[i] );
sum += a[i];
}
sort( a, a+n, compare );
int ans;
memset( vis, 0, sizeof(vis));
for( int A = n; A > 0; A--){
if( (sum%A == 0) && (sum/A >= a[0]) ){
if( dfs( n, 0, sum/A ) ){
printf("%d\n", sum/A);
break;
}
}
}
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: