题目:

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过$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】小木棍的更多相关文章

  1. [Luogu P1120]小木棍·加强版

    #\(\mathcal{Description}\) 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过 \(50\) . 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开 ...

  2. Luogu P1120 小木棍 [数据加强版] 来来来我们一起来剪枝,剪枝,剪枝、、、

    好啊...太棒了... dfs(拼到第几根木棍,这根木棍剩余长度,上一根木棍的位置) len是木棍的长度,cnt是木棍的个数 震撼人心的剪枝: 1.枚举长度从最大的木棍开始,直到sum/2,因为之后只 ...

  3. Luogu P1120 小木棍 [数据加强版]

    看了题目心中只有一个字——搜索!!! 但是很显然,朴素的搜索(回溯)绝壁超时. 剪枝&优化(要搞很多,要不然过不了) 1:从小到大搜索它们的因数,这样找到就exit. 2:将数据从大到小排序, ...

  4. 洛谷 P1120 小木棍 [数据加强版]解题报告

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

  5. 洛谷——P1120 小木棍 [数据加强版]

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍 ...

  6. 洛谷 P1120 小木棍 [数据加强版]

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

  7. 洛谷P1120 小木棍 [数据加强版](搜索)

    洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...

  8. 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)

    洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...

  9. 洛谷P1120 小木棍 [搜索]

    题目传送门 题目描述乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍 ...

  10. 洛谷 P1120 小木棍 dfs+剪枝

    Problem Description [题目链接] https://www.luogu.com.cn/problem/P1120 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不 ...

随机推荐

  1. Git命令--保存用户名和密码

    使用git各项操作时,总是会出现输入密码的弹窗,且需要多次输入,很是繁琐,通过git命令可以记住密码,避免多次操作. 一.创建保存密码的文件 1.在home文件夹,一般是 C:\Documents a ...

  2. 基于PowerShell的Lync Server管理 使用C#

    这里所说的Lync Server管理,指通过C#管理Lync账号的启用,禁用,开启账户的语音功能. Lync服务器安装后,会自动创建一个用于远程管理的应用程序,通过IIS查看,其应用程序名为: Lyn ...

  3. 工作流性能优化(敢问activiti有扩展性?)(2)

    2015/4/17 粗略看了activiti的sql的,在ativity engine包里边: 没什么头绪,先用excel记录数据量少的时候本机的性能情况:   不打印hibernate的sql:一刷 ...

  4. 前台使用load一个集合后台接受的方法

    前台: var imageCaseList = []; }; imageCaseList.push(data); $('#showData').load(url, { querys: imageCas ...

  5. Aizu 0525 Osenbei(状压+贪心)

    题意:翻煎饼,只能横着翻或者竖着翻.问最多有多少朝上? 行只有10,所以枚举一下2^10的状态,每列取0或1中最大的一个. 在枚举外面把饼翻好,枚举里面指针指一下就好.(位运算或bitset乱搞 #i ...

  6. flex在众多手机浏览器上的兼容方案(亲测华为手机自带浏览器)

    如果项目使用构建工具,可加autoprefixer来处理,[autoprefixer使用指南] 纯手写css兼容代码,需给每个使用的属性加上属性前缀 /*display: flex;写法*/ span ...

  7. click

    click简介 Click是一个Python包,用于以可组合的方式创建漂亮的命令行界面,只需要很少的代码.这是“命令行界面创建工具包”.它具有高度可配置性,但具有开箱即用的合理默认值. 点击三点: 任 ...

  8. 题解 P2626 【斐波那契数列(升级版)】

    这道题,大家一定要注意: 要对2^31取模 ! ( 本蒟蒻开始没注意到这一点,WA了 ) (不过大家在试样例的时候,试试47,出不了结果,就说明你没模2^31) 总体来说,这道题考查的知识点就两个: ...

  9. 问题001:Java软件,属于系统软件还是应用软件呢?

    在学习Java前要掌握的一些小问题: 问题一:Java软件,属于系统软件还是应用软件呢? java语言应用在计算机系统上,首先应知道计算机系统分为几部分? 计算机系统由硬件系统和软件系统两部分构成.硬 ...

  10. c++ 中十进制 八进制 十六进制 二进制转换 最简方法

    #include<iostream> using namespace std; int main() { int i; cin>>dec>>i; //cin> ...