hdu 1455 Sticks DFS 又是一个花样剪枝 ,累觉不爱

原创 2015年03月20日 09:28:42

Sticks

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


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

这题TLE了N次,也WA了很多次,算是长教训了
贴两份代码吧
别问我为什么,有代码人性!

 代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std ;

int n , d[70] , t;
bool visited[70] , notPrime[65*55];

bool cmp(const int a , const int b)
{
	return a>b ;
}

bool dfs(int len , int sum , int c , int pos)
{
	if(c == t)
	{
		return true ;
	}
	else if(len == sum)
	{
		if(dfs(len,0,c+1,0))
		{
			return true ;
		}
	}
	else
	{
		for(int i = pos ; i < n ; ++i)
		{
			if(!visited[i])
			{
				if(sum+d[i]>len)
				{
					continue ;
				}
				visited[i] = true ;
				if(dfs(len,sum+d[i],c,i+1))
				{
					return true ;
				}
				visited[i] = false ;
				//这一步剪枝很重要 ,没有可能超时 
				if(sum == 0)
				{
					return false ;
				}
				//如果下一个 长度与当前相等,那无需再次重复搜索 
				while(d[i] == d[i+1])	++i ;
			}
		}
	}
	return false ;
}

int main()
{
	while(~scanf("%d",&n) && n)
	{
		int sum = 0 ;
		for(int i = 0 ; i < n ; ++i)
		{
			scanf("%d",&d[i]) ;
			sum += d[i] ;
		}
		bool flag = false ;
		sort(d,d+n,cmp) ;
		for(int i =  d[0]; i <= sum/2 ; ++i)
		{
			if(sum%i == 0)		//剪枝,当且仅当sum能整除i时,才有可能 
			{
				t = sum/i ;
				memset(visited,false,sizeof(visited)) ;
				if(dfs(i,0,1,0))
				{
					printf("%d\n",i) ;
					flag = true ;
					break ;
				}
			}
		}
		if(!flag)
		{
			printf("%d\n",sum) ;
		}
	}
	return 0 ;
}

代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std ;

int n , d[70] ;
bool visited[70] , notPrime[65*55];

bool cmp(const int a , const int b)
{
	return a>b ;
}

bool dfs(int len , int sum , int c , int pos)
{
	if(c == n)
	{
		return true ;
	}
	else if(len == sum)
	{
		if(dfs(len,0,c,0))
		{
			return true ;
		}
	}
	else
	{
		for(int i = pos ; i < n ; ++i)
		{
			if(!visited[i])
			{
				if(sum+d[i]>len)
				{
					continue ;
				}
				visited[i] = true ;
				if(dfs(len,sum+d[i],c+1,i+1))
				{
					return true ;
				}
				visited[i] = false ;
				//这一步剪枝很重要 ,没有可能超时 
				if(sum == 0)
				{
					return false ;
				}
				//如果下一个 长度与当前相等,那无需再次重复搜索 
				while(d[i] == d[i+1])	++i ;
			}
		}
	}
	return false ;
}

int main()
{
	while(~scanf("%d",&n) && n)
	{
		int sum = 0 ;
		for(int i = 0 ; i < n ; ++i)
		{
			scanf("%d",&d[i]) ;
			sum += d[i] ;
		}
		bool flag = false ;
		sort(d,d+n,cmp) ;
		for(int i =  d[0]; i <= sum/2 ; ++i)
		{
			if(sum%i == 0)		//剪枝,当且仅当sum能整除i时,才有可能 
			{
				memset(visited,false,sizeof(visited)) ;
				if(dfs(i,0,1,0))
				{
					printf("%d\n",i) ;
					flag = true ;
					break ;
				}
			}
		}
		if(!flag)
		{
			printf("%d\n",sum) ;
		}
	}
	return 0 ;
}

与君共勉

相关文章推荐

hdu 1455 Sticks(DFS+剪枝)

原题链接: hdu 1455 题目大意: n个木棒,求原来木棒最短的长度(每个木棒等长且在数量上无限制,木棒可以未被折断过)。 思路: DFS。三个参数,当前长度,当...

hdu 1455/poj 1011 Sticks(DFS剪枝神题)

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S...
  • acm_cxq
  • acm_cxq
  • 2016年08月08日 21:05
  • 201

hdu 1455 Sticks(dfs+可行性剪枝)

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S...

HDU1455 Sticks(DFS+剪枝)

题意:George把一些等长的树枝切成了n个长度不超过50的短树枝,现在给你这些短树枝的长度,计算出原来树枝的最小长度。 思路:DFS,搜索的时候记录下每个树枝是否被匹配过,搜索的数据包括当前已经...

文章标题 HDU 1455 : Sticks(dfs+剪枝)

SticksDescription George took sticks of the same length and cut them randomly until all parts becam...

hdoj1455 poj1011 nyoj293 Sticks【DFS+剪枝】

Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 128649   Accepted: 30149 ...

HDU 1455 Sticks 深搜+剪枝

1.初始木棍的长度必须是所有木棍长度之和的约数 2.按木棍的递减顺序搜索 3.构造一根初始木棍的第一根木棍必须是最长的 4.2根长度相同的木棍没必要重复搜索 #include #includ...

hdu 1455 sticks(经典深搜+剪枝技巧)

 题意:有一堆的木棒,长度不一,它们是有一些整齐的木棒截断而成的,求最小的木棒原始长度。 思路很简单深搜,但是直接深搜的话会tle,首先可以对木棒长度进行排序从大到小,优先使用长度长的木棒,加...

hdu-1455-Sticks-深搜+剪枝

Sticks Problem Description George took sticks of the same length and cut them randomly until a...

hdu1455 Sticks ----DFS

原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=1455 一:原题内容 Problem Description George ...
  • LaoJiu_
  • LaoJiu_
  • 2016年05月17日 17:25
  • 462
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 1455 Sticks DFS 又是一个花样剪枝 ,累觉不爱
举报原因:
原因补充:

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