POJ 2011 Sticks
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 5 int n; //Number of sticks 6 7 8 bool dfs( int* stick, bool *vist, int len, int InitLen, int s, int num) // len: sum of current sticks; Initlen: target initial length 9 // s: the looking start of sticks; num: number of sticks used 10 { 11 if (num == n) 12 return true; 13 int sample = -1; //record the current stick's length 14 15 for (int i = s; i < n; i++) 16 { 17 if (vist[i] || stick[i] == sample) // Prune 3, sticks with same sticks can be used only once 18 continue; 19 20 vist[i] = true; 21 22 if ( len + stick[i] < InitLen) 23 { 24 if (dfs(stick, vist, len+stick[i], InitLen, i, num+1)) 25 return true; 26 else 27 sample = stick[i]; 28 } 29 else if (len + stick[i] == InitLen) 30 { 31 if (dfs(stick, vist, 0 , InitLen, 0, num+1)) 32 return true; 33 else 34 sample = stick[i]; 35 } 36 vist[i] = false; 37 if (len == 0) // Prune 4, the failed first sticks returns 38 break; 39 } 40 41 return false; 42 43 } 44 45 46 47 48 49 50 int cmp(const void* a, const void *b) 51 { 52 return *(int*)b - *(int*)a; 53 } 54 55 56 int main(void) 57 { 58 while( (scanf("%d", &n)) && n) 59 { 60 61 int* stick = (int*) malloc(sizeof(int) * n); 62 bool* vist = (bool*) malloc(sizeof(bool) * n); 63 int sumlen = 0; 64 65 for(int i = 0; i < n; i++) 66 { 67 scanf("%d", &(stick[i])); 68 sumlen += stick[i]; 69 vist[i]=false; 70 } 71 72 qsort(stick,n,sizeof(stick),cmp); 73 74 int maxlen = stick[0]; //Biggest stick has number 1 75 76 bool flag=false; //What is it? 77 78 // Prune 1, the shortest length must lie in [maxlen, sumlen - InitLen] 79 for (int InitLen = maxlen; InitLen <= sumlen - InitLen; InitLen++) 80 { //Prune 2, the Initlen must be the factor of number sumlen 81 if ( !(sumlen % InitLen) && dfs(stick, vist, 0, InitLen, 0, 0) ) 82 { 83 printf("%d\n", InitLen); 84 flag=true; 85 break; 86 } 87 } 88 89 if (!flag) 90 printf("%d\n", sumlen); 91 92 free(stick); 93 stick = NULL; 94 free(vist); 95 vist = NULL; 96 } 97 return 0; 98 }