Sticks(回溯和剪枝和关于局部变量的问题)

做这道题要哭了= =

之前把所有的变量都定义成全局变量,结果提交时老是RT,找不到错。后来改成局部变量就ac了= =。

Sticks(3.4.2)

Time Limit:1000MS    Memory Limit:10000KB    64bit IO Format:%I64d & %I64u

SubmitStatus

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
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int n,num[69];
int pd[69];
int cmp(int a,int b)
{
	return a>b;
}
int dfs(int len,int s,int nu)
{
	int i;
    if(s==0&&nu==0)//如果剩下的长度和剩下的木棒数为0,则成功
		return len;
    if(s==0)//如果剩下的长度为0,则重新赋值
		s=len;
    for(i=0;i<n;i++)
    {
        if(pd[i]==1)
			continue;
        if(s>=num[i])
        {
            pd[i]=1;
            if(dfs(len,s-num[i],nu-1))
				return  len;
			pd[i]=0;//如果不成功,则当前棒不使用
            if(num[i]==s||s==len)
				break;
            while(num[i]==num[i+1])
				i++;
        }
    }
	return 0;
}
int main()
{
    while(cin>>n&&n)
    {
		int i;
		int sum;
        sum=0;
		int len,k;
		for(i=0;i<n;i++)
		{
			cin>>num[i];
			sum=sum+num[i];
		}
		sort(num,num+n,cmp);
		for(len=num[0];len<=sum;len++)
		{
			memset(pd,0,sizeof(pd));
			if(sum%len==0)
			{
				k=dfs(len,0,n);
				if(k)
					break;
			}
		}
		cout<<k<<endl;
    }
    return 0;
}
/*
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
*/

Sticks(回溯和剪枝和关于局部变量的问题)

时间: 2024-10-07 13:20:00

Sticks(回溯和剪枝和关于局部变量的问题)的相关文章

POJ - 1011 - Sticks (DFS + 剪枝)

题目传送:Sticks 思路:DFS + 剪枝 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include

POJ 1011 Sticks(搜索 &amp;&amp; 剪枝 &amp;&amp; 经典)

题意 : 有n根木棍(n<=64),它们由一些相同长度的木棍切割而来,给定这n根木棍的长度,求使得原来长度可能的最小值. 分析 : 很经典的深搜题目,我们发现答案只可能是所有木棍长度总和的因数,那么我们只要去枚举因数然后搜索是否可行即可!具体实现看代码可能更容易看懂,这里不赘述.重要的是体会此类深搜的代码构建过程以及剪枝的考虑的巧妙性! #include<stdio.h> #include<algorithm> #include<string.h> using n

POJ 1011 Sticks 【DFS 剪枝】

题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 154895   Accepted: 37034 Description George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now

TZOJ 1822 Sticks DFS加剪枝

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

UVA-307 Sticks (DFS+剪枝)

题目大意:用n根长度未必相等的木棒匹配出最多数量的等长木棒. 题目分析:枚举所有可能的等长木棒的长度,通过DFS的方式逐根匹配,在此过程中要剪枝.先将木棒长度按从大到小排序,也就是说匹配每一根等长木棒时总是优先挑选长的.剪枝方案如下:1. 若第i-1根木棒在当前方案的匹配中没有用到并且length[i]==length[i-1],则第i根木棒也不可能用到:2.若已匹配成功cnt根等长木棒,而第cnt+1根匹配不成功,则要剪枝:3.若在匹配第cnt+1根木棒时,最长的那根木棒stick会第一个被选

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

poj 1011 Sticks ,剪枝神题

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

uva10400 - Game Show Math(回溯+剪枝)

题目:uva10400 - Game Show Math(回溯+剪枝) 题目大意:给出N个数,并且给出一个目标数值,要求用上面的数字(全部),并且顺序不能乱,然后用+-*/这些操作,问最终能不能得到目标数值.这里要注意给出的数会在[-32000,32000]之间, 并且要用除法的时候,只有在能整除的时候才能用.并且中间计算结果不能超过[-32000,32000]范围.如果超过这个操作不能做. 解题思路:回溯加剪枝,将每一层计算的结果都保存下来,如果在同一层发现值出现过,并且之前计算发现这样往后是

POJ 1011 递归 &amp; 回溯

题目大意:给出一些长度不大于 50 的木棍, 要求你把这些小木棍拼成*             长度相同木棍,当然长度越小越好.* 解题思路:这个题最近做了很多次,我比较有发言权了.*             思想很简单,一个接一个的把木棍拼起来,最后把木棍用光.*             关键的地方是几个剪枝技巧:*                   设所有木棍的总长度为 Sum, 最终的答案是 L. *             1. 首先要明白, Sum一定要能被 L 整除. *