【洛谷UVA307】小木棍Sticks
算法的话:dfs+超强剪枝;
(另外注意UVA上好像不接受万能头[因为万能头WA了两次,瑟瑟发抖])
思路:
最直接的思路,枚举木棍长度来dfs,但这样很容易就TLE了。
dfs的四项关键字:
1.num:剩多少切割后的木棍没有使用;
2.rest:还需要rest的长度可以凑成一个切割前的木棍;
3.len:切割前的木棍长度;
4.last:当前切割后的木棍起始的下标;(对于初始状态dfs last是1还是0好迷啊,好像初始状态是1或者0都可以ac???) 行吧就当我没说亲测不行qwq
目标条件:num=0且rest=0;
剪枝1:对于这些木棍来说,无论怎样分,若满足条件,那么木棍长度一定是总和的倍数;
剪枝2:搜索上下界:上界:所有木棍的长度和,下界:最长一根木棍的长度;
剪枝3:将切割后的木棍按从大到小排列,对于一根切割后木棍,如果它不能满足拼成一根长度为len的木棍,那么它之前的比它长的也显然不行,因此last的作用就是减少枚举次数,每次从上一次的last+1枚举就可以了;
剪枝4:如果一根木棍的长度>rest,那么对于每一根长度与之相同的木棍都不可能组合,直接跳过减少枚举次数;
剪枝5:如果当前切割后的木棍长度=len,但组装失败(如果成功就已经return true了)即返回false,因为从大到小排序,当前的切割后木棍明明可以组成成功,但后面的切割后的木棍却组成失败,说明后面的切割后的木棍长度不够或者直接构不成(剩下的切割后的任意长度和!=切割前的木棍长度),那么继续搜肯定不行;????
- #include <iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- using namespace std;
- int n, mg[], tmp, top = , tt = , vis[],T;
- int cmp(int a, int b) {
- return a > b;
- }
- bool dfs(int num , int len , int rest , int last ) {
- if (rest == && num == )
- return ;
- if (num == )//没有木棍,不能拼成的情况
- return ;
- if (rest == ) {//如果现在刚好组成一根木棍,更新rest变为枚举的切割前木棍的长度
- rest = len;
- last = ;//last再次更新为0
- }
- for (int i = last + ; i < top; i++) { //剪枝3
- if (vis[i])
- continue;
- if (mg[i] > rest) {
- while (mg[i] == mg[i + ] && i < top) i++; //剪枝4
- continue;
- }
- vis[i] = ;
- if (dfs(num - , len, rest - mg[i], i))//选择这根木棍后继续递归,判断是否可以构成一根木棍
- return ;
- vis[i] = ;
- if ((mg[i] == rest) || (len == rest))//剪枝5:这句话亲测对于提速还是很有效的
- break;
- while (mg[i] == mg[i + ] && i < top) i++;
- }
- return ;
- }
- int main() {
- while(){//while循环来输入多组数据
- memset(mg,,sizeof(mg));//因为处理多组数据,所以记得清空数组
- memset(vis,,sizeof(vis));
- tt = ;top = /*count number*/;
- cin>>n;
- if(n == ) return ;
- for (int i = ; i <= n; i++) {
- cin >> tmp;
- mg[top++] = tmp,/*存到数组里*/ tt += tmp;//求和
- }
- sort(mg + , mg + top, cmp);//从大到小排序
- for (int i = mg[]; i <= tt; i++) {//剪枝2
- if (tt % i != )//剪枝1
- continue;
- if (dfs(top - /*因为最后top会在这n个数的基础上+1,故dfs起点为top-1*/, i, i, )) {//if this i is ok to make sticks,just choose it and break;
- cout << i <<endl;
- break;
- }
- }
- }
- return ;
- }
立下凌云壮flag,咱今天绝对不理yy,咱不烦yy,咱不让yy烦
end-
【洛谷UVA307】小木棍Sticks的更多相关文章
- 洛谷P1120 小木棍
洛谷1120 小木棍 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长 ...
- 洛谷P1120 小木棍 [数据加强版](搜索)
洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...
- 洛谷P1120 小木棍(sticks数据加强版)
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...
- 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)
洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...
- 洛谷P1120小木棍[DFS]
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...
- 洛谷 P1120 小木棍 [数据加强版]解题报告
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...
- [UVA307]小木棍 Sticks
题目大意:有一堆小木棍,把它们接成相同长度的小木棍,问结果的小木棍的最小长度是多少,多组数据 题解:$dfs$,各种剪枝. 卡点:无 C++ Code: #include <cstdio> ...
- 洛谷P1120 小木棍 [搜索]
题目传送门 题目描述乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍 ...
- [洛谷P1120]小木棍 [数据加强版]
题目大意:有一些同样长的木棍,被切割成几段(长$\leqslant$50).给出每段小木棍的长度,找出原始木棍的最小可能长度. 题解:dfs C++ Code: #include<cstdio& ...
- 洛谷——P1120 小木棍 [数据加强版]
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍 ...
随机推荐
- 【记录】解决windows中nginx明明退出了,为什么还能反向代理?CMD强制杀死进程命令
博主今天遇到一个很奇怪的问题,nginx在windows中明明已经退出了,而且在任务管理器中也没发现nginx进程, 为什么还能反向代理呢? 找了半天资料终于解决,现记录如下,希望能帮助到你. 步骤一 ...
- 2018-10-2-win10-uwp-win2d-特效
title author date CreateTime categories win10 uwp win2d 特效 lindexi 2018-10-02 21:20:46 +0800 2018-6- ...
- Python2 安装教程
目录 1. 推荐阅读 2. 安装包下载 3. 安装步骤 1. 推荐阅读 Python基础入门一文通 | Python2 与Python3及VSCode下载和安装.PyCharm破解与安装.Python ...
- 在数据库中分析sql执行性能
SET STATISTICS PROFILE ON SET STATISTICS IO ON SET STATISTICS TIME ON GO /*--SQL脚本开始*/ SELECT * FROM ...
- Oracle单引号转义符
作用:Increase readability and usability (增加可读性和可用性) 用法:select q'[ select * from ]'||table_name|| ';' ...
- bzoj2306 [Ctsc2011]幸福路径 倍增 Floyd
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2306 题解 倍增 Floyd. 令 \(f[i][j][k]\) 表示走了 \(2^i\) 步 ...
- TCP TIME_WAIT和CLOSE_WAIT
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484451.html 使用如下指令查看当前Server的TCP状态 netstat -n | awk ...
- Oracle12c修改时区
Oacle12c支持可插入数据库(PDB)在一个统一的数据库(CDB)中具有不同的字符集.时区文件版本和数据库时区. 出于性能原因,Oracle建议将数据库时区设置为UTC(0:00),因为不需要转换 ...
- 11:如何解决Maven的Jar版本冲突问题
右键 Exclude,排除冲突包
- Java项目案例之---定时器的使用
定时器的使用 使用定时器,在当前时间的10秒后调用方法,输出语句 import java.text.SimpleDateFormat; import java.util.Calendar; impor ...