看似不是dfs的dfs HDU-1455

Sticks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10593    Accepted Submission(s): 3194


Problem Description
George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
 

 

Input
The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.
 

 

Output
The output file contains the smallest possible length of original sticks, one per line.
 

 

Sample Input
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
 

 

Sample Output
6
5
 
题意:原本有一些等长的棍子,棍子数量未知。这些棍子被切成任意段,每段长度50以内。输入被切后棍子的数量和长度,要求出的是未被切时的棍子长度。
 
思路:这题一开始准备用暴力做的,但想着想着感觉跟深搜类似,就尝试用深搜来写了。题目给的数据一定是会使所有木棍凑的出来原来的木棍的,所以就将原来的木棍长度从1开始到所有木棍长度和开始试。将所有木棍从大到小排序,从较长木棍开始选取,到了预定长度就继续选下一个组合成预定长度的木棍组合,如果最后能够将所有木棍成功地组合成预定的长度,这个长度就是最小长度。
重点:剪枝(不进行剪枝的话绝对会超时,剪枝不完全也会超时,亲身经历/(ㄒoㄒ)/~~)
 
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,sum_len,g_num,g_len;//所有木棍总长度,目标木棍数量,目标木棍长度
 4 int glen[70],vis[70];
 5 bool cmp(int a,int b)
 6 {
 7     return a>b;
 8 }
 9 int dfs(int cnt,int len,int pos)
10 {
11     if(cnt == g_num) return true;//木棍数量已经搜索到目标木棍数量
12     if(len == g_len) return dfs(cnt+1,0,0);//木棍长度等于目标木棍长度,目标木棍数量增加1,开始找下一木棒组合成目标木棒长度
13     for(int i=pos;i<n;i++)//从已经搜索到的木棒向后挑,向前挑长度大于已搜索的,直接不用向前
14     {
15         if(!vis[i]&&len+glen[i]<=g_len)//第i根木棒可以增加且没有被选
16         {
17             vis[i]=1;
18             if(dfs(cnt,len+glen[i],i+1)) return true;//增加后继续搜索
19             vis[i]=0;
20             if(len==0) return false;//剪枝!!!这步省去大量时间,将长度小于最大木棍长度的情况直接舍去
21             while(i+1<n&&glen[i+1]==glen[i]) i++;//后面跟前面长度一样,且前面失败了,直接跳
22         }
23     }
24     return false;
25 }
26 int main()
27 {
28     while(cin>>n)
29     {
30         if(n==0)
31             break;
32         sum_len=0;
33         int glong=0;
34         for(int i=0;i<n;i++)
35         {
36             cin>>glen[i];
37             sum_len+=glen[i];
38         }
39         for(int i=1;i<=sum_len;i++)
40         {
41             if(sum_len%i==0)
42             {
43                 memset(vis,0,sizeof(vis));
44                 g_len=i;g_num=sum_len/i;
45                 if(dfs(0,0,0))
46                     {
47                         glong=g_len;
48                         break;
49                     }
50             }
51         }
52         cout<<glong<<endl;
53     }
54     return 0;
55 }
View Code

这个dfs感觉思路跟暴力差不多,如果各位大大能够有更好点的方法,请各位大大不吝赐教O(∩_∩)O!

 
posted @ 2017-07-09 02:37  风过杀戮  阅读(288)  评论(0编辑  收藏  举报