【Luogu P1120】小木棍
题目:
乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过$50$。
现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。
给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。
分析:
可以很轻易的写出$\rm dfs$的程序:
#include <bits/stdc++.h> using namespace std; const int MAXN = ; int st[MAXN], n, s = ;
bool vis[MAXN]; void dfs(int cur, int len, int w) {
if(cur == s / len) {
cout << len << endl;
exit();
}
if(w == ) {
dfs(cur + , len, len);
return;
}
for(int i = n - ; i >= ; i--)
if(w - st[i] >= && !vis[i]) {
vis[i] = true;
dfs(cur, len, w - st[i]);
vis[i] = false;
}
} int main() {
cin >> n;
for(int i = ; i < n; i++) {
cin >> st[i];
s += st[i];
}
sort(st, st + n);
for(int i = ; i <= s; i++)
if(s % i == ) {
dfs(, i, i);
}
return ;
}
然而,上面的代码时间复杂度是$O(n! \log \sum a_i)$左右,显然不可以接受。
首先我们发现:
$1$)从按木棍大到小搜索,因为长度小的比长度大的更加灵活。
$2$)若当前剩余长度$\lt$最小的木棍的长度,那么这个方案就没用了
$3$)如果当前长度的木棍拼接无法成功,那么同样长度的木棍拼接也无法成功。
$4$)若选择这个木棍来拼接后没有成功,且当前的剩余长度$=$这个木棍的长度,应当直接退出,因为这根木棍显然要自成一个大木棍,而拼下去却失败,说明剩下的小木棍无法拼接成这根木棍。
$5$)若选择这个木棍来拼接后没有成功,且当前的剩余长度$=$我们枚举的长度$len$,应当直接退出,因为这根木棍肯定会需要用上,而这里失败了,说明它最后用不到了。
#include <bits/stdc++.h> using namespace std; const int MAXN = , inf = 1e9; int st[MAXN], n, s = , len, maxi = -inf, mini = inf;
bool vis[MAXN]; void dfs(int cur, int w, int last) {
if(cur == s / len) {
cout << len << endl;
exit();
}
if(w == ) {
dfs(cur + , len, -);
return;
}
if(w < mini) return;
for(register int i = last + ; i < n; i++)
if(w - st[i] >= && !vis[i]) {
vis[i] = true;
dfs(cur, w - st[i], i);
vis[i] = false;
while(i && st[i] == st[i - ]) i++;
if(w == st[i] || w == len) return;
}
} int main() {
cin >> n;
for(register int i = ; i < n; i++) {
cin >> st[i];
s += st[i];
maxi = max(maxi, st[i]);
mini = min(mini, st[i]);
}
sort(st, st + n, [](int x, int y){
return x > y;
});
for(register int i = maxi; i <= s; i++)
if(s % i == ) {
len = i;
dfs(, i, -);
}
return ;
}
【Luogu P1120】小木棍的更多相关文章
- [Luogu P1120]小木棍·加强版
#\(\mathcal{Description}\) 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过 \(50\) . 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开 ...
- Luogu P1120 小木棍 [数据加强版] 来来来我们一起来剪枝,剪枝,剪枝、、、
好啊...太棒了... dfs(拼到第几根木棍,这根木棍剩余长度,上一根木棍的位置) len是木棍的长度,cnt是木棍的个数 震撼人心的剪枝: 1.枚举长度从最大的木棍开始,直到sum/2,因为之后只 ...
- Luogu P1120 小木棍 [数据加强版]
看了题目心中只有一个字——搜索!!! 但是很显然,朴素的搜索(回溯)绝壁超时. 剪枝&优化(要搞很多,要不然过不了) 1:从小到大搜索它们的因数,这样找到就exit. 2:将数据从大到小排序, ...
- 洛谷 P1120 小木棍 [数据加强版]解题报告
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...
- 洛谷——P1120 小木棍 [数据加强版]
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍 ...
- 洛谷 P1120 小木棍 [数据加强版]
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...
- 洛谷P1120 小木棍 [数据加强版](搜索)
洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...
- 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)
洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...
- 洛谷P1120 小木棍 [搜索]
题目传送门 题目描述乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍 ...
- 洛谷 P1120 小木棍 dfs+剪枝
Problem Description [题目链接] https://www.luogu.com.cn/problem/P1120 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不 ...
随机推荐
- 【Android开发笔记】生命周期研究
启动 onCreate onStart onResume 退出键 onPause onStop onDestroy 锁屏 & 按住 home键 & 被其他Activity覆盖(Sing ...
- Java 中 Double 相关问题
在项目当中,对于double类型数据的使用比较频繁.尤其是处理金钱相关的数据,在使用Double类型的数据时,涉及到精度,显示,四舍五入等等问题. 1. 显示问题,当double 数据 小于 0.0 ...
- form.elements属性
form.elements属性与childNodes属性不同的是form.elements只返回的是表单元素组成的数组,包括input,textarea等
- JS事件阻止冒泡的写法
$("body").on("click", "#id", function (ev) { ev = ev || event;要写的逻辑代码 ...
- UVA 1642 Magical GCD(gcd的性质,递推)
分析:对于区间[i,j],枚举j. 固定j以后,剩下的要比较M_gcd(k,j) = gcd(ak,...,aj)*(j-k+1)的大小, i≤k≤j. 此时M_gcd(k,j)可以看成一个二元组(g ...
- 【BZOJ4650】[NOI2016] 优秀的拆分(后缀数组)
点此看题面 大致题意: 定义将一个字符串拆成\(AABB\)的形式为优秀拆分,求一个字符串所有子串的优秀拆分个数. 后缀数组 这题可是一道后缀数组黑题啊. 其实看完题解这题还是挺简单的. 大致思路 显 ...
- 【洛谷4657】[CEOI2017] Chase(一个玄学的树形DP)
点此看题面 大致题意: 有一棵树,树上编号为\(i\)的节点上有\(F_i\)个铁球,逃亡者有\(V\)个磁铁,当他在某个节点放下磁铁时,与这个节点相邻的所有节点上的铁球都会被吸引到这个节点.然后一个 ...
- Flutter Json序列号和反序列化遇到问题 Missing "part 'xxx.g.dart';"
/** * * 1.@JsonSerializable() 这是表示告诉编译器这个类是需要生成Model类的 * 2,@JsonKey 由于服务器返回的部分数据名称在Dart语言中是不被允许的, * ...
- linux怎么进home目录下
可以使用cd命令,cd命令的功能是切换到指定的目录: 命令格式:cd [目录名] 有几个符号作为目录名有特殊的含义: “/”代表根目录.“..”代表上一级目录.“~”代表HOME目录.“-”代表前一目 ...
- WARNING you have Transparen Huge Pages..
redis启动警告: WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will c ...