您的位置:首页 > 其它

POJ 1011-Sticks 简单搜索DFS

2010-08-24 11:16 417 查看
题目来源: http://acm.pku.edu.cn/JudgeOnline/problem?id=1011



解题报告:



想了两天, 看了其他的解题报告, 终于稍微想通了一点



具体的思路, 我也说不清楚, 有一份解题报告蛮清楚的, 是: http://blog.csdn.net/woshixingaaa/archive/2010/05/14/5589100.aspx





下面是我的代码:



#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;

int f[65];
int color[65];
int cnt;
int totalLength;

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

bool DFS(int length,int res,int num)//f从res开始是否可以组成长度length,还剩num根木棍组成
{
	if(num==1) //剩下一根木棍需要解决,因为之前的都组合成功了,因此剩下的一定组合成功
		return true;
	if(length==0) //成功组成了一根原始木棍,剩余要组合的木棍数为num-1,接下从0开始,继续查看是否可以组成长度totalLentgh
		return DFS(totalLength,0,num-1);
	int pre=-1;
	int i;
	for(i=res;i<cnt;i++)
	{
		if(color[i]==0 && f[i]!=pre && f[i]<=length) //如果用f[i]组成length的木棍没成功,那么后面的f[j],如果f[j]=f[i],也不会成功,直接跳过
		{
			pre=f[i];
			color[i]=1;
			if(DFS(length-f[i],i+1,num))//成功,则退出
				break;
			color[i]=0;//没成功,color[i]仍恢复到原来的状态
			if(res==0) //如果res=0,则说明在组合一根新的木棍,如果遇到了未成功,那就说明这个长度不能成功,直接返回错误
				return false;
		}	
	}
	if(i==cnt) //i枚举到cnt,一直没成功
		return false;
	else
		return true;
}

int main()
{
	while((cin >> cnt) && cnt!=0)
	{
		int sum=0;//棍子的总长度
		for(int i=0;i<cnt;i++)
		{
			cin >> f[i];
			sum+=f[i];
		}
		sort(f,f+cnt,cmp); //从大到小排列
		for(int i=f[0];i<=sum;i++) //棍子的长度要尽可能小,但显然大于等于f[]中的最大值
		{
			if(sum==i)
			{
				cout << sum << endl;
				break;
			}
			if(sum%i == 0)
			{
				totalLength=i;
				for(int j=0;j<cnt;j++)
					color[j]=0; //截下来的小木棍的访问状态
				if(DFS(totalLength,0,sum/i)) //从f[0]开始成功组成了长度为totalLength的sum/i根原始木棍
				{
					cout << totalLength << endl;
					break;
				}

			}
		}
	}
}






附录:

Sticks

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 72642Accepted: 15966
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: