题解 P1120 【小木棍 [数据加强版]】
题面
乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。
现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。
给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。
题意
有n段同样长的木棍,现在将这n段木棍随意分段(保证每段长度不超过50)。乔治比较闲,又想把它拼回原始木棍,但是又比较智障,忘了原来有多少根,长度是多少。
给出每段的长度,求出木棍最小可能长度。(使n尽量大,又要保证每段都拼上)
题解
题目看上去很简单,也很好想到这是一个搜索题,但是拿到后非常难以无法下手,数据的加强非常容易使这题超时。这是一道剪枝的经典题目
从最优性方面分析,可以做以下两种剪枝:
设所有木棍的长度和是sum,那么原长度(也就是需要输出的长度)一定能够被sum整除,不然就没法拼了,即一定要拼出整数根。
木棍原来的长度一定大于等于所有木棍中最长的那根。
综合上述两点,可以确定原木棍的长度len在最长木棍的长度与sum之间,且sum能被len整除。
所以,在搜索原木棍的长度时,可以设定为从截断后所有木棍中最长的长度开始,每次增加长度后,必须能整除sum。这样可以有效地优化程序。
从可行性方面分析,可以再做以下七种剪枝:
一根长木棍肯定比几根短木棍拼成同样长度的用处小,即短小的可以更灵活组合,所以可以对输入的所有木棍按长度从大到小排序。
在截断后的排好序的木棍中,当用木棍i拼合原始木棍时,可以从第i+1后的木棍开始搜。因为根据优化(1),i前面的木棍已经用过了。
用当前最长长度的木棍开始搜,如果拼不出当前设定的原木棍长度len,则直接返回,换一个原始木棍长度len。
相同长度的木棍不要搜索多次。用当前长度的木棍搜下去得不出结果时,用一支同样长度的还是得不到结果,所以,可以提前返回。
判断搜到的几根木棍组成的长度是否大于原始长度len,如果大于,没必要搜下去,可以提前返回。
判断当前剩下的木棍根数是否够拼成木棍,如果不够,肯定拼合不成功,直接返回。
找到结果后,在能返回的地方马上返回到上一层的递归处。
代码
这道题的思想不仅不简单,对代码能力也是一种考验。
#include<bits/stdc++.h>
using namespace std;
const int maxx = 66;
int n,maxn = -maxx,minn = maxx;
int tong[maxx];
void dfs( int res , int sum , int target , int p ) {
if( res == 0 )
{
printf("%d", target );
exit( 0 );
}
if( sum == target )
{
dfs( res - 1 , 0 , target , maxn );
return;
}
for( int i = p ; i >= minn ; i -- )
{
if( tong[ i ] && i + sum <= target )
{
tong[ i ] -- ;
dfs( res , sum + i , target , i );
tong[ i ] ++ ;
if ( sum == 0 || sum + i == target);
break;
}
}
return;
}
int main(int argc, char const *argv[])
{
scanf("%d",&n);
int x,cnt = 0,sum;
while(n--)
{
scanf("%d",&x);
if(x <= 50)
{
cnt++;
tong[x]++;
sum += x;
maxn = max(maxn,x);
minn = min(minn,x);
}
}
x = sum/2;
for(int i = maxn;i <= x;i++)
{
if(sum%i == 0)
{
dfs(sum/i,0,i,maxn);
}
}
printf("%d",sum);
return 0;
}
题解 P1120 【小木棍 [数据加强版]】的更多相关文章
- 洛谷 P1120 小木棍 [数据加强版]解题报告
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...
- 洛谷——P1120 小木棍 [数据加强版]
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍 ...
- 洛谷 P1120 小木棍 [数据加强版]
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...
- 一本通&&洛谷——P1120 小木棍 [数据加强版]——题解
题目传送 一道特别毒瘤能提醒人不要忘记剪枝的题. 首先不要忘了管理员的话.忘把长度大于50的木棍过滤掉真的坑了不少人(包括我). 显然是一道DFS题 .考虑剪枝. 找找搜索要面临的维度.状态:原始木棍 ...
- P1120 小木棍 [数据加强版] 回溯法 终极剪枝
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度 ...
- P1120 小木棍 [数据加强版]
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...
- P1120 小木棍 [数据加强版](poj 1011)
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...
- [洛谷P1120]小木棍 [数据加强版]
题目大意:有一些同样长的木棍,被切割成几段(长$\leqslant$50).给出每段小木棍的长度,找出原始木棍的最小可能长度. 题解:dfs C++ Code: #include<cstdio& ...
- 洛谷—— P1120 小木棍 [数据加强版]
https://www.luogu.org/problem/show?pid=1120 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接 ...
- Luogu P1120 小木棍 [数据加强版] 来来来我们一起来剪枝,剪枝,剪枝、、、
好啊...太棒了... dfs(拼到第几根木棍,这根木棍剩余长度,上一根木棍的位置) len是木棍的长度,cnt是木棍的个数 震撼人心的剪枝: 1.枚举长度从最大的木棍开始,直到sum/2,因为之后只 ...
随机推荐
- JVM学习记录-Java内存模型(二)
对于volatile型变量的特殊规则 关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制. 在处理多线程数据竞争问题时,不仅仅是可以使用synchronized关键字来实现,使用vo ...
- webpack4+react多页面架构
webpack在单页面打包上应用广泛,以create-react-app为首的脚手架众多,单页面打包通常是将业务js,css打包到同一个html文件中,整个项目只有一个html文件入口,但也有许多业务 ...
- C#winform使用进度条
在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口很容易假死(无法适时看到进度信息 ...
- [bug]不包含“AsNoTracking”的定义
摘要 在使用ef做查询优化的时候我们会用到AsNoTracking方法,但如果不引入命名空间,你就会出现不包含“AsNoTracking”的定义的错误. 解决办法 引入命名空间:System.Data ...
- arcgis按要求删除点位
第一篇博客 嘻嘻 上图 1
- Java代码优化笔记
指定类.方法的final修饰符 为类指定final修饰符可以让类不可以被继承,为方法指定final修饰符可以让方法不可以被重写.如果指定了一个类为final,则该类所有的方法都是final的.Java ...
- Lifting the Stone(hdu1115)多边形的重心
Lifting the Stone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- springboot —— 多数据源
本文主要介绍如何在一个springboot项目配置两个数据源(mysql和oracle): 1.引进相关依赖 <!-- https://mvnrepository.com/artifact/my ...
- Mysql数据库 的库表简易操作
一. 库的操作 1.创建数据库 创建数据库: create database 库名 charset utf8; charset uft8 可选项 1.2 数据库命名规范: 可以由字母.数字.下划 ...
- nodejs 新建项目
第一步: 新建工程-->选择nodejs-->creat 注意: 如果出错就使用第二步!! 第二步:建立express 模板的nodejs 点击下图的命令窗口,依次输入下面命令 命令: & ...