题目:

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过$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. Hibernate数据库的操作

    参考网址: https://www.cnblogs.com/jack1995/p/6952704.html 1.最简单的查询 List<Special> specials = (List& ...

  2. SpringBoot的特性

    SpringBoot的理念“习惯优于配置” 习惯优于配置(项目中存在大量的配置,此外还内置了一个习惯性的配置,无须手动进行配置) 使用SpringBoot可以方便地创建独立运行.准生产级别的基于Spr ...

  3. mysql用户权限操作

    mysql用户权限操作1.创建用户mysql -urootcreate database zabbix default charset utf8;grant all on zabbix.* to za ...

  4. 判断一个点是否在多边形区域内--C算法

    /*函数的输入:(1)当前点的坐标p(2)区域顶点数组pt[]:(3)顶点数nCount 输出: 在区域内返回TRUE,否则返回FALSE.  Point类型是一个结构: struct Point { ...

  5. git图形管理工具

    在windows下使用git命令行工具对非开发人员还是挺困难的,还好有TortoiseGit这个工具svn客户端用TortoiseSVNgit客户端用TortoiseGit 网址:https://to ...

  6. HDU5171 矩阵快速幂

    题目描述:http://acm.hdu.edu.cn/showproblem.php?pid=5171 算法: 可以先将数组a[]排序,然后序列 a1 , a2 , … , an 即为有序序列,则第一 ...

  7. linux 命令——44 top (转)

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法.top是 一个动态显示过程,即可以通过用户按键来不断刷 ...

  8. TFS看板的迭代规划

    故事点 故事点更多体现的是用户情景或者bug的规模,采用斐波拉契数列(1,2,3,5,8,13)这样的数字表示,包含如下内容: 相对工作量 复杂度 风险和不确定性 相对工作量 下面演示一个Case来说 ...

  9. CVE-2018-4878

    0x00前言 该漏洞影响 Flash Player 版本28.0.0.137以及之前的所有版本 0x01 poc Poc 这里只列出关键代码 public function triggeruaf() ...

  10. SqlServer2000事件探测器的使用

    由于公司自己开发的项目,需要与第三方软件数据库对接.我们项目用的数据库是MySQL而第三方用的是sqlserver2000.项目框架用的thinkphp5.0,通过thinkPHP新建一个模块,单独连 ...