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;    

}

 

  

你可能感兴趣的:(poj)