题面

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。

现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

题意

有n段同样长的木棍,现在将这n段木棍随意分段(保证每段长度不超过50)。乔治比较闲,又想把它拼回原始木棍,但是又比较智障,忘了原来有多少根,长度是多少。

给出每段的长度,求出木棍最小可能长度。(使n尽量大,又要保证每段都拼上)

题解

题目看上去很简单,也很好想到这是一个搜索题,但是拿到后非常难以无法下手,数据的加强非常容易使这题超时。这是一道剪枝的经典题目

从最优性方面分析,可以做以下两种剪枝:

  1. 设所有木棍的长度和是sum,那么原长度(也就是需要输出的长度)一定能够被sum整除,不然就没法拼了,即一定要拼出整数根。

  2. 木棍原来的长度一定大于等于所有木棍中最长的那根。

综合上述两点,可以确定原木棍的长度len在最长木棍的长度与sum之间,且sum能被len整除。

所以,在搜索原木棍的长度时,可以设定为从截断后所有木棍中最长的长度开始,每次增加长度后,必须能整除sum。这样可以有效地优化程序。

从可行性方面分析,可以再做以下七种剪枝:

  1. 一根长木棍肯定比几根短木棍拼成同样长度的用处小,即短小的可以更灵活组合,所以可以对输入的所有木棍按长度从大到小排序。

  2. 在截断后的排好序的木棍中,当用木棍i拼合原始木棍时,可以从第i+1后的木棍开始搜。因为根据优化(1),i前面的木棍已经用过了。

  3. 用当前最长长度的木棍开始搜,如果拼不出当前设定的原木棍长度len,则直接返回,换一个原始木棍长度len。

  4. 相同长度的木棍不要搜索多次。用当前长度的木棍搜下去得不出结果时,用一支同样长度的还是得不到结果,所以,可以提前返回。

  5. 判断搜到的几根木棍组成的长度是否大于原始长度len,如果大于,没必要搜下去,可以提前返回。

  6. 判断当前剩下的木棍根数是否够拼成木棍,如果不够,肯定拼合不成功,直接返回。

  7. 找到结果后,在能返回的地方马上返回到上一层的递归处。

代码

这道题的思想不仅不简单,对代码能力也是一种考验。

#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;
}

转载于:https://www.cnblogs.com/Chicago/p/9920785.html

题解 P1120 【小木棍 [数据加强版]】相关推荐

  1. P1120-小木棍 [数据加强版]

    吸口氧气才能过 1 #include <bits/stdc++.h> 2 #define _for(i,a,b) for(int i = (a);i < b;i ++) 3 #def ...

  2. AC日记——小木棍【数据加强版】 洛谷 P1120

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

  3. 题解 Sticks 小木棍

    题解 Sticks 小木棍 题目描述: 每组数据给出N根小木棍,把它们拼接成若干根长度相等的木棍,求该长度的最小值. 题解: 该题就是dfs深搜+剪枝 ```cpp #include<iostr ...

  4. 洛谷[P1120 小木棍]

    洛谷[P1120 小木棍] 题目: 思路: 枚举小木棒可能的长度,从数组最大值开始枚举,这个值能被总长度整除才是可行的 在使用dfs枚举小木棒的每一种可能,如果不可能就找下一个可能的长度开始枚举 注意 ...

  5. P1120 小木棍题解

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

  6. 洛谷P1120小木棍

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

  7. 洛谷 P1120 小木棍 题解

    这就是一道明显的爆搜题(人家洛谷也说了,,,),只是需要几个小小的优化,接下来为大家介绍一下: 1.将木棍先排个序(用处后面会讲),记住 长度>50 的要去掉 2.因为每一根的长度都不大于50, ...

  8. 洛谷 小木棍(暴力+剪剪剪剪枝)

    题目链接: 小木棍 - 洛谷 思路: 如果只考虑暴力,做法很简单,枚举所有可能的最终长度,都跑一遍dfs,取最小结果即可,本题难就难在大量的剪枝,具体见代码. 我的思路也是参考了大佬的博客:题解 P1 ...

  9. 小木棍(洛谷-P1120)

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

最新文章

  1. c++标准程序库异常
  2. c#对象集合去重_C# List 对象去重
  3. 天池-街景字符编码识别1-赛题理解
  4. 【华为云技术分享】【开发记录】Linux服务器维护常用命令(二)
  5. python爬取b站搜索结果播放地址_如何利用Python快速爬取B站全站视频信息
  6. 状态码为200 java 类
  7. oracle 更改分区列,ORA-14061: 不能更改索引分区列的数据类型或长度
  8. 搜索算法(DFS,BFS等)
  9. hg255d php,HG255D刷潘多拉共享惠普1020打印机的问题汇总
  10. 车辆十四自由度动力学建模分析
  11. WPS如何使参考文献对齐
  12. 借助终端软件,有效统一移动互联网和物联网
  13. iview表格序号1,2,3,4,5
  14. 愚人节,你的微信公众号图文排版够愚吗?
  15. matlab ignoreanalyticconstraints,MATLAB函数随笔之计算篇
  16. (转)金蝶KIS迷你版、标准版在查询数量金额明细账时提示“发生未知错误,系统当前操作被取消,请与金蝶公司联系”...
  17. SVN E200030: There are unfinished transactions detected
  18. Java随笔记 - 内核态和用户态
  19. 使用TeamViewer远程连接Android手机并控制
  20. WPJAM「网址导航」:最轻便快捷的WordPress网址导航插件

热门文章

  1. 网易2020校招笔试-c++开发工程师
  2. [转帖]如何使google一天内收录你的网站
  3. 连接服务器失败请检查网络是否启用修复程序,Win10出现网络连接问题的七种修复方法...
  4. Netty Bootstrapping
  5. json 数据 下载为.csv表格方法封装
  6. 2022年稀释制冷机全球市场规模达2.11亿美元,2028年有望出现突破点
  7. c语言10个评委打分不用数组,C语言编程练习题绝对经典!
  8. nginx 301 302重定向跳转配置 (一般都做301,对seo好)
  9. css实现好看的card展示效果
  10. atan2--四象限的反正切函数