DFS(剪枝) POJ 1011 Sticks

 

题目传送门

 1 /*  2  题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度;  3  DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全!  4  剪枝主要在4和5:4 相同长度的木棍不再搜索;5 若新的搜索连第一条都没组合出来,直接break;  5  详细解释:http://blog.csdn.net/lyy289065406/article/details/6647960  6 http://www.cnblogs.com/devil-91/archive/2012/08/03/2621787.html  7  这题虐我千百遍,我待她如。。 656K 0MS  8  9 10  博客随笔第100篇,纪念一下:) 11 */ 12 #include <cstdio> 13 #include <iostream> 14 #include <cstring> 15 #include <map> 16 #include <set> 17 #include <cmath> 18 #include <algorithm> 19 using namespace std; 20 21 const int MAXN = 66; 22 const int INF = 0x3f3f3f3f; 23 int a[MAXN]; 24 bool vis[MAXN]; 25 int sum; 26 int n, cnt; 27 28 bool cmp(int x, int y) 29 { 30 return x > y; 31 } 32 33 bool DFS(int len, int ans, int num, int s) 34 { 35 if (num == cnt) return true; 36 37 int pre = -1; 38 for (int i=s; i<=n; ++i) 39  { 40 if (vis[i] || a[i] == pre) continue; //Cut 4 41 42 vis[i] = true; 43 if (ans + a[i] < len) 44  { 45 if (DFS (len, ans + a[i], num, i) == true) return true; 46 else pre = a[i]; 47  } 48 else if (ans + a[i] == len) 49  { 50 if (DFS (len, 0, num+1, 1) == true) return true; 51 else pre = a[i]; 52  } 53 vis[i] = false; 54 55 if (ans == 0) break; //Cut 5 56  } 57 58 return false; 59 } 60 61 int main(void) //POJ 1011 Sticks 62 { 63 //freopen ("POJ_1011.in", "r", stdin); 64 65 while (scanf ("%d", &n) == 1 && n) 66  { 67 sum = 0; memset (vis, 0, sizeof (vis)); 68 for (int i=1; i<=n; ++i) 69  { 70 scanf ("%d", &a[i]); sum += a[i]; 71  } 72 sort (a+1, a+1+n, cmp); //Cut 1 73 74 bool flag = false; 75 for (int i=a[1]; i<=sum-i; ++i) //Cut 2 76  { 77 if (sum % i == 0) //Cut 3 78  { 79 cnt = sum / i; 80 if (DFS (i, 0, 0, 1) == true) 81  { 82 flag = true; 83 printf ("%d\n", i); break; 84  } 85  } 86  } 87 if (!flag) printf ("%d\n", sum); 88  } 89 90 return 0; 91 } 92 93 /* 94 6 95 5 96 */

 

你可能感兴趣的:(poj)