poj 1011 dfs+剪枝

据说是剪枝神题,剪枝确实是挺多的,少一个有可能都会超时。

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 100;
 7 int stick[N];
 8 bool used[N];
 9 int n, snum, slen;
10 
11 bool dfs( int num, int len, int pos )
12 {
13     if ( num == snum ) return true;
14     for ( int i = pos; i < n; i++ )
15     {
16         if ( !used[i] )
17         {
18             int tmp = stick[i] + len;
19             if ( tmp > slen ) continue;
20             used[i] = 1;
21             if ( tmp == slen )
22             {
23                 if ( dfs( num + 1, 0, 0 ) ) return true;
24                 used[i] = 0;
25                 return false;
26             }
27             else
28             {
29                 if ( dfs( num, tmp, i + 1 ) ) return true;
30                 used[i] = 0;
31             }
32             if ( len == 0 ) return false;
33             while ( stick[i] == stick[i + 1] ) i++;
34         }
35     }
36     return false;
37 }
38 
39 bool cmp( int a, int b )
40 {
41     return a > b;
42 }
43 
44 int main ()
45 {
46     while ( scanf("%d", &n), n )
47     {
48         int sum = 0;
49         for ( int i = 0; i < n; i++ )
50         {
51             scanf("%d", stick + i);
52             sum += stick[i];
53         }
54         sort( stick, stick + n, cmp );
55         stick[n] = -1;
56         int maxn = stick[0];
57         for ( int i = maxn; i <= sum; i++ )
58         {
59             if ( sum % i == 0 )
60             {
61                 snum = sum / i;
62                 slen = i;
63                 memset( used, 0, sizeof(used) );
64                 if ( dfs( 0, 0, 0 ) )
65                 {
66                     printf("%d\n", i);
67                     break;
68                 }
69             }
70         }
71     }
72     return 0;
73 }

 

posted @ 2015-07-17 11:01  hxy_has_been_used  阅读(172)  评论(0编辑  收藏  举报