Sticks
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 125918   Accepted: 29372

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 should 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

这道题的剪枝到极致了。少一点也不行,很好的搜索题。我是看了网上的代码才A的,各种剪枝。
这个题如果A了,必须要深刻理解才行,关于各种剪枝,代码中有注释
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = ;
int n, arr[maxn], Sum;
bool vis[maxn];
/*cur表示当前选择棍子的序号,diff_len为这根棍子还差多长,
sum_len初始值为总长Sum, cur_len表示搜索当前棍子长度为cur_len的棍子 */
bool dfs(int cur, int diff_len, int sum_len, int cur_len)
{
if (diff_len == )
{
sum_len -= cur_len;
if (sum_len == )//判断是否所有的棍子都取完了
{
return true;
}
for (cur = ; vis[cur]; cur++);//剪枝1,找到剩下的最长的一根,然后接着这个往下找比他小的
vis[cur] = true;
if (dfs(cur + , cur_len - arr[cur], sum_len, cur_len))//从最长的开始继续往下找 这个剪枝的威力很大,从不能TLE直接到A的差距
return true;
vis[cur] = false;
sum_len += cur_len;
}
else
{
for (int i = cur; i < n; i++)
{
/*剪枝2,如果这个棍子的长度等于上一个棍子的长度,并且上一个还不符合要求,
没有取,所以这个肯定也不能取,直接跳过 */
if (i > && arr[i] == arr[i - ] && !vis[i - ])
continue;
if (!vis[i] && diff_len >= arr[i])//如果没有取过,并且需要取的长度大于待取的才行,小小剪枝3,最普通的dfs也该有的
{
vis[i] = true;
diff_len -= arr[i];
if (dfs(i + , diff_len, sum_len, cur_len))//找下一个,普通的dfs, 剪枝4
return true;
diff_len += arr[i];
vis[i] = false;
if (arr[i] == diff_len)//剪枝5,如果走到这里,本次刚好凑成一根棍子,但是既然能走到这,肯定下面的失败了,所以返回上层dfs
break;
}
}
}
return false;
}
bool cmp(const int a, const int b)
{
return a > b;
}
int main()
{
while (cin >> n && n)
{
Sum = ;
for (int i = ; i < n; i++)
{
cin >> arr[i];
Sum += arr[i];
}
sort(arr, arr + n, cmp);//从大到小排序
memset(vis, false, sizeof(vis));
int flag = ;
for (int i = arr[]; i <= Sum / ; i++) //剪枝6,这个为什么是对的,可以举反例,假设要求的i大于Sum/2的话,那么剩下的长度和为Sum-i<i,得出来i+i>Sum,与已知矛盾,所以假设不对。
{
if (Sum % i == )
{
if (dfs(, i, Sum, i))
{
cout << i << endl;
flag = ;
break;
}
}
}
if (!flag)
cout << Sum << endl;
} return ;
}

POJ 1011 sticks 搜索的更多相关文章

  1. 搜索+剪枝——POJ 1011 Sticks

    搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...

  2. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

  3. POJ 1011 - Sticks DFS+剪枝

    POJ 1011 - Sticks 题意:    一把等长的木段被随机砍成 n 条小木条    已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析:    1. 该长度必能被总长整除    ...

  4. OpenJudge 2817:木棒 / Poj 1011 Sticks

    1.链接地址: http://bailian.openjudge.cn/practice/2817/ http://poj.org/problem?id=1011 2.题目: 总时间限制: 1000m ...

  5. POJ 1011 Sticks 【DFS 剪枝】

    题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissio ...

  6. POJ 1011 Sticks(搜索 && 剪枝 && 经典)

    题意 : 有n根木棍(n<=64),它们由一些相同长度的木棍切割而来,给定这n根木棍的长度,求使得原来长度可能的最小值. 分析 : 很经典的深搜题目,我们发现答案只可能是所有木棍长度总和的因数, ...

  7. poj 1011 Sticks (DFS+剪枝)

    Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 127771   Accepted: 29926 Descrip ...

  8. POJ 1011 Sticks dfs,剪枝 难度:2

    http://poj.org/problem?id=1011 要把所给的集合分成几个集合,每个集合相加之和ans相等,且ans最小,因为这个和ans只在[1,64*50]内,所以可以用dfs一试 首先 ...

  9. POJ 1011 Sticks(dfs+剪枝)

    http://poj.org/problem?id=1011 题意:若干个相同长度的棍子被剪成若干长度的小棍,求每根棍子原来的可能最小长度. 思路:很经典的搜索题. 我一开始各种超时,这题需要很多剪枝 ...

随机推荐

  1. memcache 操作类

    <?php /** * memcache 操作实现 * @author timeless */ class Memcache_manage { //CI原始的信息 private $_ci; p ...

  2. Linux on ASUS N550JK4700

    实际上,ASUS N550JK对Ubuntu 14.04的兼容性是相当好的,包括无线网卡.蓝牙.键盘背光的调节.触摸板的开关.音量的键盘调节都是安装后无需配置直接可以使用的,这是出乎意料的,因为这些功 ...

  3. SQL Server 连接字符串和身份验证

    SQL Server .NET Data Provider 连接字符串包含一个由一些属性名/值对组成的集合.每一个属性/值对都由分号隔开.         PropertyName1=Value1;P ...

  4. utf8_general utf8_general utf8_bin区别

    对与general来说 ß = s 是为true的 但是对于unicode来说 ß = ss 才是为true的, 其实他们的差别主要在德语和法语上,所以对于我们中国人来说,一般使用general,因为 ...

  5. while if 循环判断

    temp=input("猜一下我想的那个数字吧:") guess=int(temp) while guess!=8: temp=input("诶呀错误了在输入一次吧:&q ...

  6. JQuery UI进度条——Progressbar

    1.先引入jquery和jquery-ui的js,例子如下: <link href="JqueryUI/jquery-ui.css" rel="stylesheet ...

  7. Solr4.8.0源码分析(23)之SolrCloud的Recovery策略(四)

    Solr4.8.0源码分析(23)之SolrCloud的Recovery策略(四) 题记:本来计划的SolrCloud的Recovery策略的文章是3篇的,但是没想到Recovery的内容蛮多的,前面 ...

  8. [转]加盐hash保存密码的正确方式

    0x00 背景 大多数的web开发者都会遇到设计用户账号系统的需求.账号系统最重要的一个方面就是如何保护用户的密码.一些大公司的用户数据库泄露事件也时有发生,所以我们必须采取一些措施来保护用户的密码, ...

  9. [BZOJ 2243] [SDOI 2011] 染色 【树链剖分】

    题目链接:BZOJ - 2243 题目分析 树链剖分...写了200+行...Debug了整整一天+... 静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了. 提交之后全 WA . ————— ...

  10. vs2012 aps.net4.0/4.5尚未在web服务器上注册

    安装了vs2015后,vs2012 启动后报错: aps.net4.0/4.5尚未在web服务器上注册 解决办法: 下载微软补丁: http://blogs.msdn.com/b/webdev/arc ...