2010年5月24日

POJ1011 Sticks 搜索+强剪枝(终于AC了,分享经验)

这是本人第一次写poj结题报告,毕竟是菜鸟,如果有错误,请大家提出。

首先,这个题目是不如贪心的,我就是第一次用了贪心,一直WA,相当的悲剧,贪心错误的sample:7 15 11 8 8 8 4 3 2 1,所以大家还是全部搜索。但是全部搜索必须剪枝,不然肯定是TLE的,而且本体属于强剪枝,少剪了也是TLE。

我的剪枝如下:

1.测试的最小棒长度必须是所有棒长的因数。//sum%currentlength==0;

2.降序排列后,取第一个(也就是最长的一个进行尝试搜索),如果第一个木棒参与的搜索也失败,就停止。举例子说:比如那个贪心的sample,比如我那15凑30,假设不成功,就不必把15替换成11继续搜索。因为如果30是最小长度,则15必须能与其他木棒成功匹配。

3.比如现在我要凑30,我已经有了25,而且我正好找到了5长度的棒子。但是最终失败。至此,这个搜索就可以停止了。因为如果5后面还有比5小的长度,比如1 1 1 1 1,也正好能组成5,但是整数5的灵活性比不上5个1强,整数留到后面给其他棒子匹配也必然失败。(有点贪心的味道)

4.重复的就不用搜索了。

注意的地方,回溯必须回复好原来的数据。还有一个就是仔细啦。

 

POJ 1011
1 #include <iostream>
2 #include <algorithm>
3 #include <memory.h>
4  using namespace std;
5
6  int sticks[64]; //记录input
7  bool flags[64]; //记录是否使用过
8  int current;
9
10 bool cmp(int x,int y)
11 {
12 return x>y;
13 }
14
15 //return 2 means success 0 means failure
16 int search(int num,int start,int limit,int left)
17 {
18 for (int i=start;i<limit;++i)
19 {
20 if (flags[i]==false&&sticks[i]<=num)
21 {
22 if (num==current&&i>=1&&flags[i-1]==false) //剪枝2
23 {
24 return 0;
25 }
26 flags[i]=true;
27 --left;
28 if (num-sticks[i]==0)
29 {
30 if (left==0)
31 {
32 return 2;
33 }
34 int flag=search(current,0,limit,left);
35 if(flag==2)
36 {
37 return 2;
38 }
39 else
40 {
41 ++left;
42 flags[i]=false;
43 return 0; //剪枝3
44 }
45 }
46 int flag=search(num-sticks[i],i+1,limit,left);
47 if (flag==0)
48 {
49 ++left;
50 flags[i]=false;
51 while (i<limit-1&&sticks[i]==sticks[i+1]) //剪枝4
52 {
53 ++i;
54 }
55 continue;
56 }
57 else
58 {
59 return 2;
60 }
61 }
62 }
63 return 0;
64 }
65
66 int main()
67 {
68 int number,curLength,sum;
69 while (cin>>number)
70 {
71 if (number==0)
72 {
73 return 0;
74 }
75 sum=0;
76 for (int i=0;i<number;++i)
77 {
78 cin>>sticks[i];
79 sum+=sticks[i];
80 }
81 memset(flags,false,sizeof(bool)*number);
82
83 sort(sticks,sticks+number,cmp);
84
85 curLength=sticks[0];
86
87 for (current=curLength;current<=sum;++current)
88 {
89 if (sum%current==0) //剪枝1
90 {
91 if (search(current,0,number,number)==2)
92 {
93 cout<<current<<endl;
94 break;
95 }
96 memset(flags,false,sizeof(bool)*number);
97 }
98 }
99
100 }
101 }

 

 

 

posted @ 2010-05-24 11:34 eclipse9614 阅读(1267) 评论(0) 编辑

  

导航

统计

公告