AcWing:. 167 stick (dfs + pruning)

George brought sticks of equal length, they are cut off at random, the length of each section such that the stick is not more than 50 units of length.

Then he wants to return to these sticks is cut before the cut-off state, but can not remember how many there are initial length of the stick, and the stick initially.

Please design a program that might help calculate the minimum length of George's stick.

The length of an integer with each section are greater than zero stick representation.

Note: the stick may contain data length greater than 50, please ignore these stick during processing.

Input Format

Input data comprises a plurality of sets, each set includes two rows of data.

The first line is an integer of not more than 64, showing the section cut off after a total of how many sticks.

The second line is the length of the sections cut off after the stick, the resultant.

After the last set of data is a zero.

Output Format

For each set of data and outputs the original wooden smallest possible length, each set of data per line.

Sample input:

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

Sample output:

6
5

 

Algorithm: dfs + pruning

Solution: Pruning: 1, first search order (from large size), give priority to attempt a long stick.

      2, requires the stick has joined the monotonous, since you have to use every stick was added to a sample is added before and after.

      3, when splicing a new stick, I joined a stick, failed to show that, after a new splicing use this stick, when the stick will fail.

      4, when I now I want to join sticks stitching up, exactly equal to the length of stitching, stitching but failed, after the explanation is going to splice failure.

 

#include <the iostream> 
#include <cstdio> 
#include <algorithm> the using namespace STD; const int MAXN = + 1E5 . 7 ; int ARR [MAXN];
 int VIS [MAXN];
 int K, CNT; BOOL CMP ( int A, int B) {
     return A> B; 
} BOOL DFS ( int Stick, int CAL, int Last, int len) {
     iF (Stick> CNT) {    // when all sticks have a good fight, the search is successful return

 

 






         to true ; 
    } 
    IF (CAL == len) {     // stick has a good fight, the spell a 
        return DFS (Stick + . 1 , 0 , 0 , len); 
    } 
    int Fail = 0 ;    // pruning 2, record duplicate values 
    for ( int I = Last; I <K; I ++ ) {
         IF (VIS [I] && CAL + ARR [I] <= len && Fail =!! {ARR [I]) 
            VIS [I] = . 1 ;
             IF (DFS (Stick, CAL + ARR [I], + I . 1 , len)) {
                 return  to true  ;
            }
            VIS [I] = 0 ; 
            Fail = ARR [I];
             IF (CAL == 0 || CAL + ARR [I] == len) {     // pruning 3, prune. 4 
                return  to false ; 
            } 
        } 
    } 
    return  to false ;        // when all branches have tried, and have not successfully 
} 

int main () {
     int n-;
     the while (~ Scanf ( " % D " , & n-) && n-) {
         int SUM = 0 , max_len = 0 , X; 
        k= 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &x);
            if(x > 50) {
                continue;
            }
            sum += x;
            max_len = max(max_len, x);
            arr[k++] = x;
        }
        sort(arr, arr + k, cmp);    //剪枝1
        int i;
        for(I = max_len; I <= SUM; I ++ ) {
             IF (% I SUM =! 0 ) {
                 Continue ; 
            } 
            CNT = SUM / I;       // Get the number of sticks 
            for ( int J = 0 ; J <K; ++ J ) { 
                VIS [J] = 0 ; 
            } 
            IF (DFS ( . 1 , 0 , 0 , I)) {  
                 BREAK ; 
            } 
        } 
        the printf ( " % D \ n- " , I); 
    } 
    return  0;
}

 

Guess you like

Origin www.cnblogs.com/buhuiflydepig/p/11348544.html