poj1011 Sticks

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

经典搜索题,需要很多剪枝。
<pre name="code" class="cpp">#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
int a[100],vis[100],len,gen,n,ji;
bool cmp(int a,int b){
	return a>b;
}

int dfs(int t,int pos,int cha) //表示正在拼第t根,接下来从pos位置开始拼,拼完这根木棒还需多少长度
{
	int i,j;
	if(cha==0){
		if(t==gen)return 1;
		for(i=1;i<=n;i++){
			if(!vis[i]){
				vis[i]=1;
				if(dfs(t+1,i+1,len-a[i]))return 1; //当前这根一定是剩下最长的一根,且一定要拼
				vis[i]=0;break;
			}
		}
	}
	else{
		for(i=pos;i<=n;i++){
			if(i>1 && !vis[i-1] && a[i]==a[i-1])continue; //如果这根木棒和上一根木棒的长度相同,但是上一根没有成功,那么直接跳过这根 

			if(!vis[i] && a[i]<=cha){
				vis[i]=1;
				if(dfs(t,i+1,cha-a[i]))return 1;
				vis[i]=0;
				if(a[i]==cha)break; //如果当前这根木棒的长度恰好等于所差的长度,但是搜索不成功,那么就一定不能。
			}
		}
	}
	return 0;
}

int main()
{
	int m,i,j,flag,sum;
	while(scanf("%d",&n)!=EOF && n!=0)
	{
		sum=0;ji=0;
		for(i=1;i<=n;i++){
			scanf("%d",&a[i]);
			if(a[i]&1)ji++;
			sum+=a[i];
		}
		if(i==1){
			printf("%d\n",sum);continue;
		}
		sort(a+1,a+1+n,cmp);  //从大到小排列
		flag=0;memset(vis,0,sizeof(vis));
		for(len=a[1];len<=sum/2;len++){
			if(sum%len==0){ //必须要整除才行
				gen=sum/len;
			    if(len&1){   //如果总长度是奇数,但个数小于总根数,那么直接下一个循环
    				if(ji<gen)continue;
    			}
    			if(~len&1){  //如果总长度是偶数,但是有奇数个奇数,那么直接下一个循环
			    	if(ji&1)continue;
			    }
				if(dfs(1,1,len)){
					flag=1;printf("%d\n",len);break;
				}
			}
		}
		if(!flag)printf("%d\n",sum);
	}
	return 0;
}



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

时间: 2024-12-25 11:50:08

poj1011 Sticks的相关文章

poj1011 Sticks DFS+回溯

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://poj.org/problem?id=1011 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

POJ1011 Sticks 【剪枝】

Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 122771   Accepted: 28441 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 or

poj-1011 sticks(搜索题)

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 h

POJ1011 Sticks DFS+剪枝

Description 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位.然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度.请你设计一个程序,帮助乔治计算木棒的可能最小长度.每一节木棍的长度都用大于零的整数表示. Input 输入包含多组数据,每组数据包括两行.第一行是一个不超过64的整数,表示砍断之后共有多少节木棍.第二行是截断以后,所得到的各节木棍的长度.在最后一组数据之后,是一个零. Output 为每组数据,分别输出

POJ2676 Sticks

木棒 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 147267   Accepted: 34890 Description 乔 治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位.然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多 少木棒以及木棒的初始长度.请你设计一个程序,帮助乔治计算木棒的可能最小长度.每一节木棍的长度都用大于零的整数表示. Input 输入包含多组数据,每

poj练习题的方法

poj1010--邮票问题 DFSpoj1011--Sticks dfs + 剪枝poj1020--拼蛋糕poj1054--The Troublesome Frogpoj1062--昂贵的聘礼poj1077--Eightpoj1084--Square Destroyerpoj1085--Triangle War(博弈,極大極小搜索+alpha_beta剪枝)poj1088--滑雪poj1129--Channel Allocation 着色问题 dfspoj1154--letters (dfs)p

POJ 搜索题集

poj1010--邮票问题 DFS poj1011--Sticks dfs + 剪枝 poj1020--拼蛋糕 poj1054--The Troublesome Frog poj1062--昂贵的聘礼 poj1077--Eight poj1084--Square Destroyer poj1085--Triangle War(博弈,極大極小搜索+alpha_beta剪枝) poj1088--滑雪 poj1129--Channel Allocation 着色问题 dfs poj1154--lett

Sticks(poj1011/uva307)

题目大意: 乔治有一些碎木棒,是通过将一些相等长度的原始木棒折断得到的,给出碎木棒的总数和各自的长度,求最小的可能的原始木棒的长度:(就是将一些正整数分组,每组加起来和相等,使和尽可能小) 一开始做poj 32ms过,但uva3000 ms 都超时...而且poj discuss里给出了一组bT数据,最后uva 0.2sac的代码也跑了3 .4秒左右.discuss里的大牛据说什么奇偶性剪枝0.01ms过,可惜搜了半天也没找到具体方法.这题就这样过好了..(参考各种空间博客才艰难ac.不过此题实

【poj1011】 Sticks

http://poj.org/problem?id=1011 (题目链接) 题意:给出一大堆小棍子的长度,需要把他们拼成几根长度相等的大棍子,求大棍子的最短长度. solution  经典搜索题,剪枝剪到手软.  要得到最小的原始木棍长度,可以按照分段数的长度,依次枚举所有的可能长度L.每次枚举L时,dfs判断是否能用小木棍拼合出整数个L.如果不剪枝,就等着狂TLE吧.  最优性:  1.所有木棍的长度和一定能一定能整除大木棍长度L.  2.大木棍长度一定>=小木棍最长长度.  可行性:  3.