题目描述:

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 Output6

5

代码如下:

 #include<iostream>
#include<cstring>
#include<cstdlib> using namespace std; int stick[],visit[];
int n,len,flag,sum; int cmp(const void * a,const void * b)
{
return (*(int *)a - *(int *)b);
} void dfs(int rest,int complete,int start);
int main()
{
while(cin >> n && n)
{
sum = ;
flag = false;
for(int i = ;i < n;i++)
{
cin >> stick[i];
sum += stick[i];
}
qsort(stick,n,sizeof(int),cmp);//从长到短的排序,先排短木棒的话,很
memset(visit,,sizeof(visit));//有可能出现后面一根木棒都不能填补的情况
for(len = stick[];len <= sum/;len++)//枚举区间应该在sum/2,因为最少
{ //组成两根木棒
if(sum % len == )//拼好的木帮要整除木棒和,这样才能平均分
{
dfs(len,,);
if(flag)//出现符合情况,就退出循环
break;
}
}
if(flag)
cout << len << endl;
else
cout << sum << endl;
}
return ;
} void dfs(int rest,int complete,int start)//rest为拼当前木棒时还缺少的长度
{//complete为已经拼好的木棒数,start为从哪根木棒开始搜索待拼的木棒
if(flag)
return;
if(rest == )
{
complete++;
if(complete == (sum / len))
flag = ;
else
{
int k = ;
while(visit[k])
k++;
visit[k] = ;
dfs(len - stick[k],complete,k+);
visit[k] = ;//回溯
}
}
else
{
for(int i = start;i < n;i++)
{
if(i > && !visit[i - ] && (stick[i - ] == stick[i]))
continue;//如果当前木棒和前一根木棒是一样的长度,而前一根木棒没有用过的话,那么这根木棒也一定不使用的
if(!visit[i] && stick[i] <= rest)
{
visit[i] = ;
dfs(rest - stick[i],complete,i + );
visit[i] = ;
if(rest == stick[i])//注释1 && 注释2(注释1 和 注释2 是同一种解释)
break;
}
}
}
return;
} /*注释1*/
/*搜索过程中,如果这个时候rest==d,也就是说刚刚开始拼一根新的木棒,
* 假如这时把没有用过的最长的一根木棒拼上去,但最后无解的话,
* 那么便不需要去尝试把后面的木棒拼上去了,
* 因为后面不管第几次拼,总要用到这根木棒的,
* 所以出现这种情况,不管后面再尝试拼哪根,最后都一定是无解的。*/ /*注释2*/
/* 搜索过程中,如果遇到一根木棒,它的长度恰好等于rest,
* 但把它拼上去之后无解,那么也便不需要再尝试把后面的木棒拼上去了*/

代码分析:

剪枝非常重要,之前超时了好多次。。。

参考地址:http://www.cnblogs.com/staginner/archive/2011/08/17/2143614.html

Sticks(poj 1011)的更多相关文章

  1. Sticks POJ - 1011 少林神棍 dfs四次剪枝

    http://poj.org/problem?id=1011 题意:若干根棍子被截成小段的木棒,现在给你这些木棒,问最短可以拼出的棍子长度. 题解:搜索,dfs(r,m) 二个参数分别代表还剩r个木棒 ...

  2. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

  3. OpenJudge 2817:木棒 / Poj 1011 Sticks

    1.链接地址: http://bailian.openjudge.cn/practice/2817/ http://poj.org/problem?id=1011 2.题目: 总时间限制: 1000m ...

  4. POJ 1011 - Sticks DFS+剪枝

    POJ 1011 - Sticks 题意:    一把等长的木段被随机砍成 n 条小木条    已知他们各自的长度,问原来这些木段可能的最小长度是多少 分析:    1. 该长度必能被总长整除    ...

  5. 搜索+剪枝——POJ 1011 Sticks

    搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...

  6. POJ 1011 Sticks 【DFS 剪枝】

    题目链接:http://poj.org/problem?id=1011 Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissio ...

  7. poj 1011 Sticks (DFS+剪枝)

    Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 127771   Accepted: 29926 Descrip ...

  8. POJ 1011 Sticks dfs,剪枝 难度:2

    http://poj.org/problem?id=1011 要把所给的集合分成几个集合,每个集合相加之和ans相等,且ans最小,因为这个和ans只在[1,64*50]内,所以可以用dfs一试 首先 ...

  9. poj 1011 Sticks

    Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 126238   Accepted: 29477 Descrip ...

随机推荐

  1. smarty如何处理状态值的显示

    比如状态,有效或者无效.这个数据库中保存的是1或者2这样的字段. 显示在列表的时候不能是1或者2吧. 以前,我都是在后台foreach,处理的.感觉处理之后,前台就不灵活了.这个值就被替换成了文字. ...

  2. VS2010 win32项目windows窗体程序 向导生成代码解析

    目录: 1.Win32项目的windows窗体程序的向导生成了如下代码 2.手工生成代码如下 3.当消息队列中没有消息需要处理,我们可以利用这段时间处理我们自己的任务 1.Win32项目的window ...

  3. URAL 1297 Palindrome(后缀数组+ST表)

    [题目链接] http://acm.timus.ru/problem.aspx?num=1297 [题目大意] 求最长回文子串,并输出这个串. [题解] 我们将原串倒置得到一个新的串,加一个拼接符将新 ...

  4. UVA - 699The Falling Leaves(递归先序二叉树)

    The Falling Leaves Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Sub ...

  5. Good Luck in CET-4 Everybody!(博弈)

    Good Luck in CET-4 Everybody! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  6. HDU5280 Senior&#39;s Array(简单DP)

    题目链接:pid=5280">传送门 题意: 给定一个长度为n的序列,和一个改动的值p,必须从原序列中选一个位置改动成p, 求改动后的区间和的最大值. 分析: 枚举位置+最大区间和. ...

  7. SQL2008中Merge的用法(轉載)

    在SQL2008中,新增了一个关键字:Merge,这个和Oracle的Merge的用法差不多,只是新增了一个delete方法而已.下面就是具体的使用说明: 首先是对merge的使用说明: merge ...

  8. handlebar.js使用

    官方网站:http://handlebarsjs.com/ 下载及查看使用帮助,或者用百度cdn引用 一.定义模板 <script id="entry-template" t ...

  9. JavaScript 验证提交文件的信息

    前言 目前工作任务终于告一段落了,今天发现之前写的文件上传的代码有点小瑕疵,就是上传图片如果超过 2M 就会出错,因为七牛云好像限制了上传图片的大小,所以就用 JavaScript 在文件选中之后,上 ...

  10. Android 开发笔记“浅谈DDMS视图”

    DDMS 的全称是Dalvik Debug Monitor Service,即Dalvik调试监控服务,是一个可视化的调试监控工具.它主要是对系统运行后台日志的监控,还有系统线程,模拟器状态的监控.此 ...