小木棍(最优性剪枝、可行性剪枝)

一、问题描述

  • 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,已知每段的长都不超过 50 。现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。给出每段小木棍的长度,编程帮他找出原始最短木棍的可能长度

二、输入格式

  • 第一行为一个整合 N,表示砍过以后的小木棍总数,其中 \(N\leq 60\)
  • 第二行为 N 个用空格隔开的整数,表示 N 根小木棍的长度

三、输出格式

  • 输出文件仅一行,表示要求的原始最短木棍的可能长度

四、样例输入

9
5 2 1 5 2 1 5 2 1

五、样例输出

6

六、思路分析

  • 利用搜索枚举所有可能出现的情况 every_len,从 1 开始,枚举到它们所有的和(最坏的情况,只有一根),枚举的状态是当前木棍数 now,当前已获得木棍长度 now_len,当前要处理的序号 now_code,递归从 now_len 开始,以 now_len 是否为 0 为标志,如果为 0,则需要传入一个新的 now_len(判断下一个数),如果不为 0,若等于 every_len,说明找到一组满足条件的数,传入一个新的 now,并将 now_len 置为 0,如果不等于 every_len,说明还未达到 every_len,那么需要加数字,再进行判断,通过 now_code 传递下标,如果下标没变,说明这个 every_len 不合适,退出递归,直至判断完所有 every_len。

七、剪枝分析

  • 上下界剪枝——上界为所有小木棍的和,下界为最长的小木棍,即原木棍长度一定大于最长的木棍
  • 优化搜索顺序——对原数据排序,避免重复情况
  • 最优性剪枝——原木棍长度一定可以被所有木棍长度之和整除,不然无法拼出整数根
  • 可行性剪枝 1——相同长度的木棍不需要搜索多次,因此有相同长度的木棍,就不用再次进入递归
  • 可行性剪枝 2——找到结果后,立马返回上层递归处
  • 可行性剪枝 3——搜索到的木棍组成的大于 every_len ,停止搜索

八、代码

#include<iostream>
#include<cstdlib>
#include <cstring>
#define MAX_N 64 using namespace std; int n,sum_len,len[MAX_N+1],every_len,num;
bool used[MAX_N+1];
bool legal; int compare(const void* e1,const void* e2)
{
return *(int *)e2-*(int *)e1;
} void dfs(int now,int now_len,int now_code)
{
if(legal)
return;
if(now_len == every_len) //可行性剪枝 2
{
dfs(now+1,0,0);
return;
}
if(now == num)
{
legal = true;
return;
}
if(now_len == 0)
{
for(int i = 1; i <= n; i++)
if(!used[i])
{
used[i] = true;
dfs(now,len[i],i+1);
used[i] = false;
return;
}
}
int j=0;
for(int i = now_code;i <= n;i++)
{
if(now_len+len[i] <= every_len && !used[i] && (len[i] != len[j])) //可行性剪枝 3,可行性剪枝 1
{
j = i;
used[i] = true;
dfs(now,now_len+len[i],i+1);
used[i] = false;
}
}
return;
} int main()
{
ios::sync_with_stdio(false);
while(cin >> n && n)
{
sum_len = 0;
for(int i = 1;i <= n; i++)
{
cin >> len[i];
sum_len += len[i];
}
qsort(len+1,n,sizeof(int),compare); //优化搜索顺序
memset(used,false,sizeof(bool));
for(every_len = len[1];every_len <= sum_len;every_len++) //上下界剪枝
if(sum_len % every_len == 0) //最优性剪枝
{
legal = false;
num = sum_len/every_len;
dfs(1,0,1);
if(legal)
break;
}
cout<<every_len<<endl;
}
return 0;
}

深搜的剪枝技巧(三)——Sticks(可行性剪枝、上下界剪枝、最优性剪枝)的更多相关文章

  1. ACM 海贼王之伟大航路(深搜剪枝)

    "我是要成为海贼王的男人!" 路飞他们伟大航路行程的起点是罗格镇,终点是拉夫德鲁(那里藏匿着"唯一的大秘宝"--ONE PIECE).而航程中间,则是各式各样的 ...

  2. 一本通例题埃及分数—题解&&深搜的剪枝技巧总结

    一.简述: 众所周知,深搜(深度优先搜索)的时间复杂度在不加任何优化的情况下是非常慢的,一般都是指数级别的时间复杂度,在题目严格的时间限制下难以通过.所以大多数搜索算法都需要优化.形象地看,搜索的优化 ...

  3. 【深搜加剪枝】【HDU1455】【Sticks】

    题目大意:有一堆木棍 由几个相同长的木棍截出来的,求那几个相同长的木棍最短能有多短? 深搜+剪枝 具体看代码 #include <cstdio> #include <cstdlib& ...

  4. poj1190 生日蛋糕(深搜+剪枝)

    题目链接:poj1190 生日蛋糕 解题思路: 深搜,枚举:每一层可能的高度和半径 确定搜索范围:底层蛋糕的最大可能半径和最大可能高度 搜索顺序:从底层往上搭蛋糕,在同一层尝试时,半径和高度都是从大到 ...

  5. 一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>

    题目传送 显然是道深搜题.由于蛋糕上表面在最底层的半径确认后就确认了,所以搜索时的面积着重看侧面积. 找维度/搜索面临状态/对象:当前体积v,当前外表面面积s,各层的半径r[],各层的高度h[]. 可 ...

  6. 【笔记】「pj复习」深搜——简单剪枝

    深搜--简单剪枝 说在最前面: 因为马上要 NOIP2020 了,所以菜鸡开始了复习qwq. pj 组 T1 ,T2 肯定要拿到满分的,然后 T3 , T4 拿部分分, T3 拿部分分最常见的做法就是 ...

  7. Hdu3812-Sea Sky(深搜+剪枝)

    Sea and Sky are the most favorite things of iSea, even when he was a small child.  Suzi once wrote: ...

  8. UVA 10160 Servicing Stations(深搜 + 剪枝)

    Problem D: Servicing stations A company offers personal computers for sale in N towns (3 <= N < ...

  9. hdu 1518 Square(深搜+剪枝)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! ...

随机推荐

  1. 变量.argsort()的用法

    a=[1,2,5,9,7,3]a=np.array(a)order = a.argsort() # 从小到大排序,并返回索引值print('order=',order)order1= a.argsor ...

  2. 【MySQL】数据库中间件Atlas

    1.介绍 Atlas 是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目.它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改 ...

  3. nodejs中的_filename和_dirname

    _filename和_dirname都不是全局对象下的属性,它们都是模块下的 _filename:返回当前模块文件被解析过后的绝对路径,该属性并非全局,而是模块作用域下的 console.log(_f ...

  4. 一张图带你看懂原始dao与SQL动态代理开发的区别-Mybatis

    //转载请注明出处:https://www.cnblogs.com/nreg/p/11156167.html 1.项目结构区别: 2.开发区别: 注:其中原始dao开发的实现类UserDaoImpl ...

  5. PHP防止SQL注入攻击和XSS攻击

    代码如下: /** * 防SQL注入和XSS攻击 * @param $arr */ function SafeFilter (&$arr) { $ra=Array('/([\x00-\x08, ...

  6. 谈谈OAuth1,OAuth2异同

    ##一.写在前面在收集资料时,我查询和学习了许多介绍OAuth的文章,这些文章有好有坏,但大多是从个例出发.因此我想从官方文档出发,结合在stackoverflow上的一些讨论,一并整理一下.整理的内 ...

  7. 利用ViewStub实现布局懒惰加载

    这个问题也是头条面试官问的,本身没什么难度,但以前确实没仔细研究过. 1.使用介绍 ViewStub是一种不可见的尺寸为0的View,用来实现布局资源的懒加载.当ViewStub被设置为用户可见或其  ...

  8. Linux文本处理三剑客之grep及正则表达式详解

    Linux文本处理三剑客之grep及正则表达式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Linux文本处理三剑客概述 grep: 全称:"Global se ...

  9. 如何将scratch3.0的作业自动提交到后台数据库

    大家都知道Scratch3.0开发后,默认是可以下载文件到电脑,但是如果是作为商业系统来说,我们需要将作业自动的提交到后台,因此有了这篇文章. 首先,我们来分解下开发步骤: 1.在菜单栏新增一个上传到 ...

  10. kafka安装测试报错 could not be established. Broker may not be available.

    修改 config 下配置文件 vim server.properties 配置本机ip listeners=PLAINTEXT://192.168.174.128:9092 执行命令时 bin/ka ...