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

POJ2676 Sticks

时间:2017-08-14 11:33:07      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:ide   截断   amp   设计   mic   程序   mil   code   poj1011   

木棒
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 147267   Accepted: 34890

Description

乔 治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多 少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。

Input

输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。

Output

为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

Sample Input

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

Sample Output

6
5

Source

Translator

北京大学程序设计实习, Xie Di
 
【题解】

搜索思路:枚举最终的木棒长度len,计算出木棒的根数cnt,依次搜索每根木棒由哪些木棍组成。
剪枝一(搜索顺序):木棍长度从大到小排序,先尝试长的木棍,同时每根木棒上的木棍也应该是按照长度递减的
剪枝二(枚举可行性):从小到大枚举最终木棒长度,只有该长度是长度总和的约数时才进行搜索
剪枝三(重复冗余剪枝):记录当前刚搜完的木棍长度,若搜索失败,当前木棒不再尝试同样长度的其它木棍
剪枝四(搜索可行性):如果在一个尚未包含任何木棍的木棒中,尝试搜索当前最长的木棍失败,直接返回。
                                  ——by 李煜东

实验证明这四个剪枝缺一不可(mmp)

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <algorithm>
 6 #define max(a, b) ((a) > (b) ? (a) : (b))
 7 
 8 const int MAXN = 60;
 9 
10 inline void read(int &x)
11 {
12     x = 0;char ch = getchar(),c = ch;
13     while(ch < 0 || ch > 9)c = ch, ch = getchar();
14     while(ch <= 9 && ch >= 0)x = x * 10 + ch - 0, ch =getchar();
15     if(c == -)x = -x;
16 }
17 
18 int n,num[MAXN],sum,ma,len,ans,b[MAXN];
19 
20 int dfs(int now, int size, int last)
21 {
22     if(now == ans + 1)return 1;
23     if(size == len)return dfs(now + 1, 0, 0);
24     int pre = -1;
25     for(register int i = last + 1;i <= n;++ i)
26     {
27         if(!b[i] && size + num[i] <= len && num[pre] != num[i])
28         {
29             b[i] = 1;
30             if(dfs(now, size + num[i], i))return 1;
31             b[i] = 0;
32             pre = i;
33             if(size == 0)return 0;
34         }
35     }
36     return 0;
37 }
38 
39 int main()
40 {
41     while(scanf("%d", &n) && n)
42     {
43         //init
44         ma = sum = 0;
45         //in
46         for(register int i = 1;i <= n;++ i) read(num[i]), sum += num[i], ma = max(ma, num[i]);
47         std::sort(num + 1, num + 1 + n, std::greater<int>());
48         //dfs
49         for(len = ma;len <= sum;++ len)
50         {
51             ans = sum/len;
52             if(ans * len == sum)
53             {
54                 memset(b, 0, sizeof(b));
55                 if(dfs(1,0,0))break;
56             }
57         }
58         printf("%d\n", len);
59     }
60     return 0;
61 }
POJ1011 Sticks

 

 

 

POJ2676 Sticks

标签:ide   截断   amp   设计   mic   程序   mil   code   poj1011   

原文地址:http://www.cnblogs.com/huibixiaoxing/p/7356482.html

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