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 }

 

posted on 2016-09-28 17:10  wusichen  阅读(137)  评论(0编辑  收藏  举报