POJ 1011 sticks 搜索
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
0Sample Output
6
5Source
#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 搜索的更多相关文章
- 搜索+剪枝——POJ 1011 Sticks
搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- POJ 1011 - Sticks DFS+剪枝
POJ 1011 - Sticks 题意: 一把等长的木段被随机砍成 n 条小木条 已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析: 1. 该长度必能被总长整除 ...
- OpenJudge 2817:木棒 / Poj 1011 Sticks
1.链接地址: http://bailian.openjudge.cn/practice/2817/ http://poj.org/problem?id=1011 2.题目: 总时间限制: 1000m ...
- POJ 1011 Sticks 【DFS 剪枝】
题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissio ...
- POJ 1011 Sticks(搜索 && 剪枝 && 经典)
题意 : 有n根木棍(n<=64),它们由一些相同长度的木棍切割而来,给定这n根木棍的长度,求使得原来长度可能的最小值. 分析 : 很经典的深搜题目,我们发现答案只可能是所有木棍长度总和的因数, ...
- poj 1011 Sticks (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127771 Accepted: 29926 Descrip ...
- POJ 1011 Sticks dfs,剪枝 难度:2
http://poj.org/problem?id=1011 要把所给的集合分成几个集合,每个集合相加之和ans相等,且ans最小,因为这个和ans只在[1,64*50]内,所以可以用dfs一试 首先 ...
- POJ 1011 Sticks(dfs+剪枝)
http://poj.org/problem?id=1011 题意:若干个相同长度的棍子被剪成若干长度的小棍,求每根棍子原来的可能最小长度. 思路:很经典的搜索题. 我一开始各种超时,这题需要很多剪枝 ...
随机推荐
- lsmod
http://blog.csdn.net/yuan892173701/article/details/8960607 抽空写下
- 项目任务管理(TaskMgr)技术篇
判定是否为枚举型:type.IsEnum 应用原型:如果是枚举返回字符型,如果是其他类型直接返回: object value = pro1.FieldType.IsEnum ? pro1.GetVal ...
- PL/SQL developer export/import (转)
export/import图标为灰色:原因:相关应用程序没有关联菜单栏 --> Tools --> Import Tables... --> Oracle Import Export ...
- window7 64位安装Python
Python下载地址:https://www.python.org/download/releases/2.7.8/ 选择64位的安装,然后双击打开下载的文件,默认一步步安装. 其中有一个步骤如下图: ...
- Unity GUI编程
脚本语言:C# 附上一张图说明Unity GUI编程中可用的控件:(可能有遗漏) 下面列出一些例子来说明: 1.Groups : 在固定Layout模式中起到组织可用项的功能,它让你在屏幕的一个区域中 ...
- JButton 做图片框
JButton setHorizontalTextPosition(SwingConstants.CENTER);// 在水平方向文字位于图片中央 setVerticalTextPosition(Sw ...
- 数学 ZJOI 2012 数列
#include <iostream> #include <cstring> #include <cstdio> using namespace std; ; st ...
- Combination Sum —— LeetCode
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...
- postgresql使用文档之一 初始化数据存储区
17.2. 创建一个数据库集群(Database Cluster) 在你能做任何事情之前,你必须在磁盘上初始化一块存储空间.我们称这为一个数据库集群(database cluster). 一个Data ...
- BagTest
package cn.aust.zyw.demo; import java.util.Iterator; /** * Created by zyw on 2016/2/17. */ public cl ...