POJ 1011 Sticks(DFS + 剪枝)

来源:互联网 发布:淘宝 情趣内衣 买家秀 编辑:程序博客网 时间:2024/06/06 17:20

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

95 2 1 5 2 1 5 2 141 2 3 40

Sample Output

65
题目大意:乔治有一堆长短相同的木棒,他随意地将木棒切成几段直到每段的长度都小于50。现在他想把这些木棒拼回去,但是他忘了原来木棒的长度,请你帮他编写一个程序来计算原来木棒的最小长度。

解题思路:见程序注释。

代码如下:

#include <cstdio>#include <algorithm>#include <cstring>using namespace std;bool used[65];int n,stick[65];int cnt;int cmp(int a,int b){return a > b;}//len原木棒的长度,needlen当前木棒拼接为原木棒所需要的长度,num剩余可用木棒的数量 int dfs(int len,int needlen,int num){//如果当前可用木棒的数量和当前木棒拼接为原木棒所需要的长度均为0,说明找到len,返回len的值 if(num == 0 && needlen == 0)return len;//如果当前木棒拼接为原木棒所需要的长度为0,说明已经拼接好一根木棒,将len赋值给needlen if(needlen == 0)needlen = len;//从第一根木棒开始遍历 for(int i = 0;i < n;i++){//如果这根木棒已经被使用,就跳过这一次循环 if(used[i])continue;//如果当前木棒的长度小于等于所需木棒的长度 if(needlen >= stick[i]){//标记此木棒已被使用 used[i] = true;//在此基础上深搜 if(dfs(len,needlen - stick[i],num - 1))return len;//搜索失败,将使用标记清除 used[i] = 0;//如果当前木棒的长度等于拼接成原木棒所需要的长度或原木棒的长度等于拼接成原木棒所需要的长度,跳出循环//因为木棒长度从大到小排列,当前木棒已经是最合适的了,如果当前木棒都不能拼接成功,后面的木棒都不行了// if(stick[i] == needlen || len == needlen)break;//搜索失败,跳过所有长度相同的木棒 while(stick[i] == stick[i + 1])i++;}}return 0;}int main(){while(scanf("%d",&n) != EOF && n){int sum = 0;int ans;for(int i = 0;i < n;i++){scanf("%d",&stick[i]);sum += stick[i];}sort(stick,stick + n,cmp);for(int len = stick[0];len <= sum;len++){memset(used,0,sizeof(used));if(sum % len == 0){ans = dfs(len,0,n);if(ans)break;}}printf("%d\n",ans);}return 0;}


0 0