hdu1455 Sticks(搜索+剪枝+剪枝+.....+剪枝)

网友投稿 245 2022-09-17

hdu1455 Sticks(搜索+剪枝+剪枝+.....+剪枝)

Sticks

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

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

Source

​​ACM暑期集训队练习赛(七)​​

Recommend

lcy   |   We have carefully selected several similar problems for you:   ​​1258​​​  ​​​1067​​​  ​​​1045​​​  ​​​2553​​​  ​​​1426​​

​​Statistic​​ |

​​Submit​​ |

​​Discuss​​ |

​​Note​​

我觉得我要死了  参考了别人的代码  理解了一晚上

自己敲了下。在hdu过了  可是在​​nyoj293​​死活TLE。。

明明和别人同样的代码。最后顺序  变量名 什么都改  还是不行。。我选择死亡  nyoj的我不刷了

对于这道题而言 剪枝在搜索中的重要性体现的淋漓尽致。

剪枝1:小木棒的长度 越长约束力也就越大,灵活度就越小(能够组合的长度越少),所以首先对小木棒的长度排序

剪枝2:所有小木棒的长度之和肯定能够整除原来小木棒的长度

剪枝3:如果我们已经使用过木棒4 5 6无法完成拼接,下次再出现5 4 6肯定是不可能的 所以搜索时要避免这种情况

剪枝4:如果当前搜索的结果是正确的,对于每根小木棒 都要使用,如果发现没有使用  直接退出

剪枝5:如果当前木棒的长度等于拼接木棒需要的长度  ,并且这根木棒没有被使用,那么直接退出。(即使找到比他小的几个组合为这个木棒长度 也是无用)

剪枝6:如果当前木棒的长度已经出现过并且没有被使用 那么直接跳过

#include #include #include #include using namespace std;int a[100];int n;bool vis[100];bool cmp(int a, int b){ return a > b;}bool dfs(int s, int c, int l, int index, int sum){ if(sum == l) { index++; if(index == c) return true; s = 0; sum = 0; } for(int i = s; i < n; i++)//剪枝3 { if(!vis[i] && sum + a[i] <= l) { vis[i] = true; if(dfs(s + 1, c, l, index, sum + a[i])) return true; vis[i] = false; if(sum == 0) return false;//剪枝4:如果这根小棍找不到匹配的 直接结束 if(l - sum == a[i]) return false;//剪枝5:如果当前小木棍的长度等于所需的长度 直接结束 while(a[i] == a[i + 1]) i++;//剪枝6:去除重复的 } } return false;}int main(){ while(scanf("%d",&n)&&n) { int sum=0; for(int i = 0; i < n; i++) { scanf("%d", &a[i]); sum += a[i]; } sort(a, a + n, cmp);//剪枝1 for(int i = a[0]; i <= sum; i++) { if(sum % i == 0)//剪枝2 { memset(vis, false, sizeof(vis)); if(dfs(0, sum / i, i, 0, 0)) { printf("%d\n", i); break; } } } } return 0;}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Qt中OpenGL窗口创建的几种形式
下一篇:nyoj304节能(区间dp)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~