码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1011 Sticks

时间:2019-09-08 18:09:02      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:解释   就是   cst   oid   sizeof   重要   不用   turn   思路   

题目传送门

//原址有中文翻译

解题思路:

求出总长度sum和小棒最长的长度max,则原棒可能的长度必在max~sum之间,然后从小到大枚举max~sum之间能被sum整除的长度len,用dfs求出所有的小棒能否拼凑成这个长度,如果可以,第一个len就是答案。

 

下面就是关键的了,就是这道题dfs的实现和剪枝的设计:

      1.以一个小棒为开头,用dfs看看能否把这个小棒拼凑成len长,如果可以,用vis[i]记录下用过的小棒,然后继续以另外一个小棒为开头,以此类推。

      2.小棒的长度从大到小排序,这个就不解释了。

      3.如果当前最长的小棒不能拼成len长,那么就返回前一步,更改前一步的最长小棒的组合情况(这里不能是全部退出),不用再继续搜索下去了。

      4.最重要的,就是比如说17,9,9,9,9,8,8,5,2……如果当前最长小棒为17,它与第一个9组合之后dfs发现不能拼成len,那么17就不用和后面所有的9组合了,而直接和8开始组合。这个剪枝直接从TLE到16MS,很强大。

//转自http://blog.sina.com.cn/s/blog_6635898a0100lgq0.html

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 int n,a[70],ans;
 9 bool flag,vis[70]; 
10 
11 bool cmp(int k,int b) {
12     return k > b;
13 }
14 
15 inline void dfs(int deep,int now,int i) {
16     if(flag) return ;
17     if(now == 0) {
18         int k = 0;
19         while(vis[k]) k++;
20         vis[k] = true;
21         dfs(deep + 1,a[k],k + 1);
22         vis[k] = false;
23         return ;
24     }
25     if(now == ans) {
26         if(deep == n + 1) flag = true;
27         else dfs(deep,0,1);
28         return ;
29     }
30     for(int j = i;j <= n; j++) {
31         if(!vis[j] && now + a[j] <= ans) {
32             if(!vis[j-1] && a[j] == a[j-1]) continue;
33             vis[j] = true;
34             dfs(deep + 1,now + a[j],j + 1);
35             vis[j] = false;
36         }
37     }
38 }
39 
40 int main()
41 {
42     while(true) {
43         scanf("%d",&n);
44         if(n == 0) return 0;
45         flag = false;
46         int sum = 0;
47         for(int i = 1;i <= n; i++) {
48             scanf("%d",&a[i]);
49             sum += a[i];
50         }
51         sort(a + 1,a + n + 1,cmp);
52         for(ans = a[1];ans < sum; ans++) 
53             if(sum % ans == 0) {
54                 memset(vis,0,sizeof(vis));
55                 dfs(0,0,1);
56                 if(flag) break;
57             }
58         printf("%d\n",ans);
59     }
60     return 0;
61 }

 

POJ 1011 Sticks

标签:解释   就是   cst   oid   sizeof   重要   不用   turn   思路   

原文地址:https://www.cnblogs.com/lipeiyi520/p/11487527.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!