博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[洛谷P1120] 小木棍 [数据加强版]
阅读量:5262 次
发布时间:2019-06-14

本文共 1963 字,大约阅读时间需要 6 分钟。

洛谷题目链接:

题目描述

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

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

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

输入输出格式

输入格式:

输入文件共有二行。

第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65

(管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!)

第二行为N个用空个隔开的正整数,表示N根小木棍的长度。

输出格式:

输出文件仅一行,表示要求的原始木棍的最小可能长度

输入输出样例

输入样例#1:

9

5 2 1 5 2 1 5 2 1

输出样例#1:

6

说明

2017/08/05

数据时限修改:

-#17 #20 #22 #27 四组数据时限500ms

-#21 #24 #28 #29 #30五组数据时限1000ms

其他时限改为200ms(请放心食用)

简述一下题意:给出n根木棍长度(长度大于50的自己过滤掉),判断可以由几根长度相同的木棍截成这些长度. 输出最小的长度.

样例由(1+5),(1+5),(1+5),(2+2+2)组成

简单分析一下:

题目要求由几根长度相同的木棍能拆成这么多木棍,然而这个并没有任何规律能够直接推出这个长度,但是显然这个长度是没有什么公式能直接推出来的.所以考虑爆搜.

那么就考虑一下如何优化剪枝了.我们可以得到一下优化策略:

  1. 题目要求要由整数根的木条拆成这些小木棍,那么可以在枚举原木棍长度的时候先判断,能被所有木棍长度之和整除的才可能是答案.
  2. 原木棍长度至少是所有木棍中长度最大的那根,否则长度最大的那根小木棍无法被组成.
  3. 在搜索的时候可以从大到小搜,因为长度大的木棍能更快组成一根长木棍,这样可以减少分支数.
  4. 枚举到当前长度如果可以和已经组成的长度组成一根完整的木棍(或是目前组成的长度为0),那么在回溯的时候可以直接break.因为如果枚举到这个长度可以与之前组成的一些长度组成一根新的木棍,那么如果它能搜出最终的答案,就不会回溯了.如果不能搜出答案,那么继续往后枚举加入的长度也不会再搜出答案了.
  5. 由于数据小,所以可以直接桶排记录数据,枚举剩余木棍长度时只要枚举到所有木棍中的最小值.
  6. 枚举搜索的原木棍长度时只需要枚举到总长度的\(\frac{1}{2}\),如果搜到了总长度的\(\frac{1}{2}\)还没搜出答案的话,说明这些木棍一定是从一根木棍上切下来的.

然后稍微注意一下输入,没什么细节了.下面上代码:

#include
using namespace std;const int N=65+5;const int inf=2147483647;int n, cnt = 0, tot = 0, b[N];int ans = inf, mx = -inf, mn = inf;bool used[N];bool cmp(int a,int b){ return a > b;}void dfs(int sti,int lim,int sum,int maxx){ if(sti == 0){printf("%d\n",lim); exit(0);} if(sum == lim){dfs(sti-1,lim,0,mx); return;} for(int i=maxx;i>=mn;i--){ if(i+sum <= lim && b[i]){ b[i]--; dfs(sti,lim,sum+i,i); b[i]++; if(sum == 0 || sum+i == lim) break; } }}int main(){ int x; cin >> n; for(int i=1;i<=n;i++){ cin >> x; if(x <= 50){ b[x]++ , tot += x; mx = max(mx , x); mn = min(mn , x); } } for(int i=mx;i<=tot/2;i++) if(tot % i == 0) dfs(tot/i,i,0,mx); printf("%d\n",tot); return 0;}

转载于:https://www.cnblogs.com/BCOI/p/8869063.html

你可能感兴趣的文章
《般若波罗蜜多心经》全文及解释
查看>>
数字类型内置方法
查看>>
[转载]使用Openfiler构建ESXI网络共享存储iSCSI
查看>>
Android基于mAppWidget实现手绘地图(十四)–在一个应用中使用多个地图
查看>>
iOS开发核心动画之粒子效果
查看>>
实验1 查看CPU和内存,用机器指令和汇编指令编程
查看>>
Beta 冲刺(1/7)
查看>>
算法之经典排序-冒泡排序(bubble sort)
查看>>
python之Django实现商城从0到1
查看>>
利用CSS3中的clac()实现按照屏幕分辨率自适应宽度
查看>>
stm32单片机时钟中断的配置
查看>>
linq查询结果转换为指定字段类型的list集合
查看>>
verilog PLI 实例
查看>>
JavaScript_判断浏览器种类IE、FF、Opera、Safari、chrome及版本
查看>>
PAT 1015. Reversible Primes
查看>>
simulink模型与1ms和10ms等不同速率的处理
查看>>
c++ int to string 实现
查看>>
17.cat
查看>>
ITE3101 Introduction to Programming
查看>>
[LeetCode] 267. Palindrome Permutation II 回文全排列 II
查看>>