Sticks(UVA - 307)【DFS+剪枝】
Sticks(UVA - 307)
算法
DFS+剪枝
1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大木棍,要求这个拼接成的大木棍的长度最小。问最小长度是多少。(注意,在接下来的介绍中,将最后的大木棍表述为拼接木棍,小木棍还是叫小木棍)
2.看完这个题,基本思路是从一个小木棍开始找,找到一个未使用的小木棍后拼接,当拼接成的长度是所有小木棍长度和的约数时,就暂时把它定义为拼接木棍的最小长度,然后计算最后需拼接成多少个这个长度的拼接木棍,然后继续寻找,达到这个长度后累加,如果实在没有,重新定义拼接木棍的最下长度。
如果按部就班的按照上面的基本思路做肯定会超时的,而且涉及的点比较多,因为当你所找到的那个最小长度不能够让所有小木棍都能拼接成时,还需继续寻找,这样过于复杂。
那么换个思路,既然是拼接木棍,那么最终拼接木棍的最小长度一定大于等于所有小木棍的最大长度。
那么我们就可以从小木棍的最大长度这个地方开始枚举拼接木棍的长度,这是其中一个可以优化的地方。那什么时候到头呢,拼接木棍的长度最大可以枚举到所有小木棍的长度和,然后就不能再大了。考虑到拼接木棍的长度是小木棍长度和的约数,那么就可以枚举到长度和/2,因为大于长度和/2的部分就没有长度和的约数了(除了长度和本身),这样可以节省一定的时间。当满足条件时,直接退出循环,输出即可,如果循环了所有约数都不满足,直接输出长度和即可。
下面介绍几个剪枝的地方:
- 将存储小木棍长度的数组从大到小排序,这样做的原因是长度大的小木棍相对于长度小的小木棍一定有相对较小的选择,这样在一定情况下节省了时间。
- 枚举拼接木棍的长度时,只考虑约数(小木棍长度和的约数),其余的无需考虑。
- 如果当前木棍与前一个木棍长度相同,并且前一个木棍拼接失败,那么直接跳过当前木棍即可。
- 当目前拼接长度为0时,但尝试了所有的木棍都没有拼接成功,则证明这个拼接木棍的长度无法拼成,return false即可。
3.这道题是一道典型的DFS剪枝题目,涉及的剪枝比较多,稍有一点没涉及到就会TLE。
C++ 代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1000;
int n, units[N];
int sum_length; /*所有小木棍的总长度*/
bool st[N]; /*标记当前小木棍是否被使用*/
int res; /*拼接长度*/
int cnt; /*在拼接长度为res时最终能形成的拼接木棍的个数*/
bool dfs(int len, int k, int i) /*len表示当前的拼接长度,k表示满足res的拼接木棍的个数,i表示下标为i的这个木棍已经考虑完,再枚举时从下一个木棍开始枚举即可*/
{
if(len == res)
{
k++; /*达到拼接长度时,累加拼接木棍的个数*/
len = i = 0;
}
if(k == cnt) return true;
for(int j = i + 1; j < n; j++)
{
if(st[j]) continue; /*当前木棍已经被使用,则不能再使用*/
if(units[j] == units[j-1] && !st[j-1]) continue; /*前一个木棍与它长度相同,但没被使用,那该木棍也无需再验证是否需要使用了*/
if(units[j] + len > res) continue; /*大于拼接长度,则不能考虑*/
st[j] = true;
if(dfs(len + units[j], k, j))
return true;
st[j] = false;
if(len == 0)
return false;
}
return false;
}
int main()
{
while(cin >> n && n)
{
sum_length = 0;
for(int i = 0; i < n; i++)
{
cin >> units[i];
sum_length += units[i];
}
sort(units, units + n, greater<int>());
for(res = units[0]; res <= sum_length / 2; res ++)
{
memset(st, 0, sizeof st);
if(sum_length % res != 0) continue;
cnt = sum_length / res; /*预测的初始木棒个数*/
st[0] = true; /*标记第一个最长的小木棍被使用*/
if(dfs(units[0], 0, 0))
{
cout << res << endl;
break;
}
}
if(res > sum_length / 2) /*大于它时,说明没有可形成的长度,直接输出长度和即可*/
cout << sum_length << endl;
}
}
Sticks(UVA - 307)【DFS+剪枝】的更多相关文章
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- poj 1011 Sticks (DFS+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 127771 Accepted: 29926 Descrip ...
- poj 1011 :Sticks (dfs+剪枝)
题意:给出n根小棒的长度stick[i],已知这n根小棒原本由若干根长度相同的长木棒(原棒)分解而来.求出原棒的最小可能长度. 思路:dfs+剪枝.蛮经典的题目,重点在于dfs剪枝的设计.先说先具体的 ...
- *HDU1455 DFS剪枝
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- hdu1455 dfs+剪枝
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- POJ 3009 DFS+剪枝
POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...
- poj 1724:ROADS(DFS + 剪枝)
ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10777 Accepted: 3961 Descriptio ...
- DFS+剪枝 HDOJ 5323 Solve this interesting problem
题目传送门 /* 题意:告诉一个区间[L,R],问根节点的n是多少 DFS+剪枝:父亲节点有四种情况:[l, r + len],[l, r + len - 1],[l - len, r],[l - l ...
- HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)
Counting Cliques Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
随机推荐
- USB Key
随着互联网和电子商务的发展,USB Key作为网络用户身份识别和数据保护的“电子钥匙”,正在被越来越多的用户所认识和使用.本文对USB Key的产生和未来的发展趋势作了一个简单的介绍. 目前市场上见到 ...
- 【HttpRunner v3.x】笔记—6. 测试用例-teststeps-RunRequest
之前我们了解了config里的各项参数,今天来了解另一个重要部分--teststeps,在这之前,先看看测试用例的分层模型. 一.测试用例分层模型 一个testcase里(就是一个pytest格式的P ...
- 深入了解Redis【一】源码下载与参考资料准备
引言 一直在使用redis,但是却没有系统的了解过它的底层实现,准备边学习边记录,深入了解redis. 打算分析以下几个方面: redis的基本类型及底层原理与java对比,每种数据类型的使用场景 r ...
- JavaWeb实现图片上传功能
首先导入文件上传的jar包 然后在Spring-servlet.xml文件中设置上传文件解析器 <!--上传文件解析器--> <bean id="multipartReso ...
- vue 通过css实现输入框居中输入
今天开发时突然想写blog了,水一下(o゚v゚)ノ css代码 .inputStyle { text-align: center;/*主要就是这个,下面的都是样式*/ width: 6rem; hei ...
- Git 不能提交空目录?我也是醉了!
Git 不能提交空目录?我也是醉了! 背景 最近在提交文件时,因为是空的 Maven 项目结构,发现 Git 空目录死活不能提交,还以为是我自己在 .gitignore 文件中忽略了,在网上查了下,原 ...
- python之cookie与session
cookie概念 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. cookie的工作原理是:由服务器 ...
- git仓库下拉和上传
git仓库比较方便,可以实现白天在公司写的代码,下班之前上传到git仓库,晚上在另一台电脑上直接下拉下来,其实感觉和开发用的svn差不多 在另一篇博客里面写到,需要先在git里面新增好仓库和成员之后, ...
- python之map
python之Map函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # map()函数使用举例 # 功能: ...
- 基于Ant Design Vue封装一个表单控件
开源代码 https://github.com/naturefwvue/nf-vue3-ant 有缺点本来是写在最后的,但是博文写的似乎有点太长了,估计大家没时间往下看,于是就把有缺点写在前面了,不喜 ...