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 经典深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1455 Sticks Time Limit: 2000/1000 MS (Java/Others)  ...
  • liusuangeng
  • liusuangeng
  • 2014年09月04日 17:00
  • 869

ACM-DFS之Sticks——hdu1455

ACM DFS Sticks hdu1455 经典剪枝
  • lx417147512
  • lx417147512
  • 2014年04月07日 14:53
  • 1664

HDU1455 Sticks(DFS+剪枝)

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

hdu1455Sticks【深搜剪枝】

又是卡了3天的题,终于结束了,也是怪中己太不细心== 和上一篇博客之中做的点击打开链接 hdu1518拼正方形类似,这个题开始就一直超时,开始以为是只带入了一个表示木棍长度的参数,根数每次都算导致的...
  • zhou_yujia
  • zhou_yujia
  • 2015年12月16日 14:54
  • 409

hdu 1455 Sticks 【dfs剪枝】

点击打开链接 题意:  给你n根棍子,棍子两两之间可以合并,合并之后形成的棍子长度是两棍子之和。       问你要保证所有棍子一样长,棍子的最短长度是多少。 题解:  枚举...
  • zoro_n
  • zoro_n
  • 2017年04月05日 15:12
  • 84

Sticks POJ1011 hdu1455 (深度优先搜索DFS)

Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 122528   Accepted: 28390 ...
  • u013021513
  • u013021513
  • 2014年11月15日 21:33
  • 544

hdu 1455 Sticks (dfs 经典剪枝)

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S...
  • u010228612
  • u010228612
  • 2013年07月17日 09:18
  • 690

累觉不爱

人人都带着虚伪的面具,人性,taire
  • u014639822
  • u014639822
  • 2014年04月10日 16:06
  • 100

【DFS】hdu 1455 Sticks

http://acm.hdu.edu.cn/showproblem.php?pid=1455 分析:与hdu 1518类似:http://blog.csdn.net/killua_99/article...
  • yduqytd
  • yduqytd
  • 2013年08月13日 20:14
  • 415

觉累不爱

写博客时候只要点击切换到MarkDown编辑器,浏览器直接卡死,电脑风扇狂转。心好塞,以为是电脑QQ浏览器兼容性问题,换了谷歌,火狐问题依旧。网搜了下,上一年遇到这问题的不少,现在依旧未解决,效率不敢...
  • u012171129
  • u012171129
  • 2017年03月29日 15:11
  • 39
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 1455 Sticks DFS 又是一个花样剪枝 ,累觉不爱
举报原因:
原因补充:

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