Poj--1011(回溯,强剪枝)

2014-11-25 17:26:56

思路:这题在Uva写过,现在重写竟然还是不顺手Orz...

   几个剪枝:(1)木棍从大到小排序,优先取大,这样可减少递归深度

        (2)枚举结果长度时要使之整除总长

        (3)在递归考虑过程中如果发现 i 和 i-1 根木棍同长但 i-1 未取,那么 i 也不取

        (4)如果在从头开始构成一根目标棒时就失败,那么之后也不能成功

 1 /*************************************************************************
 2     > File Name: p1011.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Tue 25 Nov 2014 12:32:31 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int n,sum;
28 int v[100];
29 int vis[100];
30 
31 bool Dfs(int pos,int now,int lsum,int tar){
32     if(lsum == sum)
33         return true;
34     for(int i = pos; i <= n; ++i) if(!vis[i]){
35         if(i > 1 && v[i] == v[i - 1] && !vis[i - 1])
36             continue;
37         if(now + v[i] < tar){
38             vis[i] = 1;
39             bool flag = Dfs(i + 1,now + v[i],lsum,tar);
40             vis[i] = 0;
41             if(flag) return true;
42             else if(now == 0) return false;
43         }
44         else if(now + v[i] == tar){
45             vis[i] = 1;
46             bool flag = Dfs(1,0,lsum + tar,tar);
47             vis[i] = 0;
48             if(flag) return true;
49             else return false;
50         }
51     }
52     return false;
53 }
54 
55 int main(){
56     while(scanf("%d",&n) != EOF && n){
57         int tmax = 0;
58         sum = 0;
59         memset(vis,0,sizeof(vis));
60         for(int i = 1; i <= n; ++i){
61              scanf("%d",&v[i]);
62              tmax = max(tmax,v[i]);
63              sum += v[i];
64         }
65         sort(v + 1,v + n + 1,greater<int>());
66         for(int i = tmax; i <= sum; i ++) if(sum % i == 0){
67              if(Dfs(1,0,0,i)){
68                  printf("%d\n",i);
69                  break;
70              }
71         }
72     }
73     return 0;
74 }

 

posted @ 2014-11-25 17:29  Naturain  阅读(126)  评论(0编辑  收藏  举报