poj 1011 Sticks (DFS+剪枝)

原创 2015年07月08日 12:52:52

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

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


题目链接:http://poj.org/problem?id=1011


题目大意:有n根木棍,用它们拼成一些等长的木棍,求拼出的木棍的最短长度。


解题思路:这题的时间限制特别严格。DFS+剪枝,剪枝较多。首先由多到少枚举木棍数目num,即从n到1,要满足木棍总长度是num的倍数,且拼出的长度要不小于最长的木棍长度,否则无法拼,搜索到答案后退出循环,保证求出的木棍长最短。

剪枝:1.木棍由长到短排序。

   2.访问过的木棍或者加上当前木棍长度后超过了目标长度,则跳过本次循环。

   3.若当前木棍和上一根木棍长度相同并且上一根木棍没用到,则跳过本次循环。

   4.dfs中标记开始木棍下标。


代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[66],vis[66];
int n,num,m;
bool p;
int cmp(int a,int b)
{
	return a>b;
}
void dfs(int st,int cur,int cnt)
{
	if(p||cnt==num)
	{
		p=true;
		return ;
	}
	for(int i=st;i<n;i++)
	{
		if(vis[i]||cur+a[i]>m)    //访问过的木棍或者加上当前木棍长度后超过了目标长度,则跳过本次循环
			continue;
		if(i-1&&!vis[i-1]&&a[i]==a[i-1])    //若当前木棍和上一根木棍长度相同并且上一根木棍没用到,则跳过本次循环。
			continue;
		if(a[i]+cur==m)
		{
			vis[i]=1;
			dfs(0,0,cnt+1);
			vis[i]=0;
			return;				//循环里后面的值都在dfs中求过了,这里直接返回上一层
		}
		if(a[i]+cur<m)
		{
			vis[i]=1;
			dfs(i+1,a[i]+cur,cnt);
			vis[i]=0;
			if(cur==0)           //cur为0时,直接返回上一层
				return ;
		}
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF&&n)
	{
		int sum=0;
		p=false;
		memset(vis,0,sizeof(vis));
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			sum+=a[i];
		}
		sort(a,a+n,cmp);
		for(num=n;num>=1;num--)
		{
			if(sum%num||a[0]>sum/num)
				continue;
			m=sum/num;
			dfs(0,0,0);
			if(p)
				break;
		}
		printf("%d\n",m);
	}
	return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 1011 Sticks(DFS+剪枝)详细注释

题目链接:http://poj.org/problem?id=1011Sticks Time Limit: 1000MSMemory Limit: 10000K Total Submissions...
  • dlgjzlaj
  • dlgjzlaj
  • 2017年08月07日 15:58
  • 123

poj 1011 sticks(木棒) (dfs+剪枝)

Description 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始...
  • Loi_YZS
  • Loi_YZS
  • 2016年09月27日 16:16
  • 338

poj(1011)——Sticks(经典的dfs+剪枝)

题目的大致意思是: 现在有n根木棍,然后需要把它们拼成同样长度的木棍,问满足这个条件的最短的长度是多少? 想法嘛:那肯定是dfs把长度搜一遍就好,但问题的关键是这里会超时。那么就要用到剪枝的原理了...
  • ACMer_hades
  • ACMer_hades
  • 2015年07月26日 17:12
  • 1090

POJ 1011 Sticks(搜索剪枝)

有以下几个剪枝,按难度排序: 下文‘部分’代表切割后的小棒子 1.做假设的长度一定可以整除所有部分长度之和 2.当选择一个部分刚好能把现在组合的这根棒子补全,而之后的棒子无法补全时,直接返回fa...
  • Baoli1008
  • Baoli1008
  • 2015年03月31日 12:21
  • 338

搜索+剪枝——POJ 1011 Sticks

搜索+剪枝——POJ 1011 Sticks 博客分类:  算法     非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来,本来是想找点手感的,不想在原先思路的基础上,竟把...
  • txl16211
  • txl16211
  • 2014年08月05日 09:51
  • 576

poj 1011 Sticks(经典搜索问题:DFS+剪枝)

题目:出自http://poj.org/problem?id=1011 转自:http://www.qiyeku.com/xinwen/654439.html 描述:给出一定数量的小木棒的长度,它...
  • u010064842
  • u010064842
  • 2013年04月21日 12:28
  • 1691

POJ 1011 Sticks 【深搜+剪枝】

原题链接:  http://poj.org/problem?id=1011
  • u012844301
  • u012844301
  • 2014年07月21日 20:01
  • 415

poj1011——Sticks(dfs+剪枝)

DescriptionGeorge took sticks of the same length and cut them randomly until all parts became at mos...
  • blue_skyrim
  • blue_skyrim
  • 2017年04月11日 15:18
  • 308

Sticks(DFS+剪枝+贪心)

Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 115807   Accep...
  • u012689588
  • u012689588
  • 2014年04月02日 21:09
  • 523

POJ 1011 Sticks(深搜+强剪枝)

题意:给你很多短的棒子,它们的长度告诉你,它们是由很多根长的棒子截出来的,问你这些短的棒子可以组成很多个相等的长棒子,求单个长棒子最短是多少? 想法:设所有棒子的总长为sum,seglen为单个长棒...
  • Triple_WDF
  • Triple_WDF
  • 2015年09月25日 00:07
  • 270
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 1011 Sticks (DFS+剪枝)
举报原因:
原因补充:

(最多只允许输入30个字)