poj 1011 Sticks 减枝搜索

题意

  有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;    
}

  

原文地址:https://www.cnblogs.com/yefeng1627/p/2993889.html