题解 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,因为之后只 ...
随机推荐
- Android studio的gradle
1. gradle的基本概念 gradle构建* Android Studio使用`Gradle`构建工具,Eclipse的ADT插件使用的是`Ant`构建工具* 构建:生成app的过程,执行一些的命 ...
- .2-浅析express源码之applicaiton模块(1)-咸鱼方法
上一节讲了express的入口文件,当执行主函数,会调用app.init方法,这个方法就来源于application模块. 这个模块有很多方法,目前仅仅过一下初始化方法: app.init = fun ...
- vs2017调试浏览器闪退
工具>选项>项目和解决方案> Web项目",取消选中"浏览器窗口关闭时停止调试器"
- 数据库中存储日期的字段类型到底应该用varchar还是datetime
将数据库中存储时间的数据类型改为varchar(),这时最好让这些时间是数据库中自动生成的(一个没有格式的输入也可能会导致输出错误),因为存储类型为varchar(),所以获取到的值也就被认为是一个字 ...
- c# 对文件的各种操作
C# 获取文件名及扩展名 string aFirstName = aFile.Substring(aFile.LastIndexOf("\\") + 1, (aFile.LastI ...
- hive 中的正则表达式
背景: 前几天拿来apache日志,用hive的正则进行匹配,发现匹配出来的字段算是NULL,但是我用RegexBuddy工具显示能够匹配的到啊!例子如下(我拿正常的apache日志来比较,我的apa ...
- Android - ANR小结
Application Not Responding 在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Applicatio ...
- Python traceback 异常处理
刚接触Python的时候,简单的异常处理已经可以帮助我们解决大多数问题,但是随着逐渐地深入,我们会发现有很多情况下简单的异常处理已经无法解决问题了,如下代码,单纯的打印异常所能提供的信息会非常有限. ...
- Linux 安装redis,redis发布订阅,持久化
安装redis 1.安装redis的方式 -yum (删除这个yum安装的redis,我们只用源码编译安装的) -rpm -源码编译 2.删除原本的redis yum remove redis -y ...
- python网络爬虫抓取动态网页并将数据存入数据库MySQL
简述以下的代码是使用python实现的网络爬虫,抓取动态网页 http://hb.qq.com/baoliao/ .此网页中的最新.精华下面的内容是由JavaScript动态生成的.审查网页元素与网页 ...