BZOJ 2135 刷题计划(贪心,求导,二分)【BZOJ 修复工程】
整理的算法模板合集: ACM模板
点我看算法全家桶系列!!!
实际上是一个全新的精炼模板整合计划
题目链接
https://hydro.ac/d/bzoj/p/2135
是 hydro 的 BZOJ 修复工程 !(我也去领了一点题慢慢修着玩,这题就是我修的嘿嘿嘿)
题目描述
为了提高自己的实力, gx 想要制定一个合理的刷题计划。这里我们用实数来表示题目的难度,并且把刷题计划中由题目难度组成的序列称为刷题序列。gx 刷题最喜欢循序渐进的方式,最理想的情况莫过于刷题序列是个等差数列了。但是这很难做到,于是我们定义一个刷题序列 aaa 的偏移值 p(a)=∑i=2n(ai−ai−1−L)2\displaystyle p(a)=\sum_{i = 2}^{n}(a_i-a_{i-1}-L)^2p(a)=i=2∑n(ai−ai−1−L)2,其中 LLL 是给定的一个常数。
现在 gx 的老师已经布置给他 nnn 道必做题,同时他还有空余时间从 OJ 上找 mmm 道题来刷。他不希望改变这 nnn 道必做题的相对顺序,但是选做题的难度以及在数列中的位置都是任意的(OJ 上的题目太多了,随你怎么挑)。
gx 希望你帮他设计一个刷题序列,使得该序列的偏移值最小。
输入格式
输入的第一行包含三个数: n,m,Ln, m, Ln,m,L。nnn 是整数,表示必做题有 nnn 道, mmm 是整数,表示选做题有 mmm 道,LLL 是实数。
第二行包含 nnn 个实数,依次表示每道必做题的难度。
输出格式
输出一个实数,表示最小的偏离值。保留三位小数。
4 3 1.0
1 4 5 3
8.000
数据规模与约定
对于 30%30\%30% 的数据, n≤500n\le 500n≤500,m≤200m\le 200m≤200。
对于 70%70\%70% 的数据,n≤2×104n\le 2\times 10^4n≤2×104,m≤105m\le 10^5m≤105。
对于 100%100\%100% 的数据, 1≤n≤5×1041\le n\le 5\times 10^41≤n≤5×104,1≤m≤1081\le m\le 10^81≤m≤108,−100≤L≤100-100\le L\le 100−100≤L≤100,∣ai∣≤100|a_i|\le 100∣ai∣≤100。
存在 50%50\%50% 的数据,L=0L=0L=0。
提示
样例说明:将原序列 (1,4,5,3)(1,4,5,3)(1,4,5,3) 变成 (1,2,3,4,5,4,3)(1,2,3,4,5,4,3)(1,2,3,4,5,4,3) ,偏离值为 8.008.008.00。
Solution
题目可以转化为,一个有 nnn 个数的序列,你有 mmm 次操作,每次操作可以在两个数之间插入一个任意大小的数,求得到的新序列的最小偏差值: p(a)=∑i=2n(ai−ai−1−L)2\displaystyle p(a)=\sum_{i = 2}^{n}(a_i-a_{i-1}-L)^2p(a)=i=2∑n(ai−ai−1−L)2
序列一共有 nnn 个数,每两个数之间可以插入若干个数,显然最开始一共有 n−1n-1n−1 个位置可以插入,也即一共有 n−1n-1n−1 个差值 ai−ai−1a_i-a_{i-1}ai−ai−1。对于一个序列 a1,a2,a3a_1,a_2,a_3a1,a2,a3,一共有两个位置可以操作,让我们在 a1,a2a_1,a_2a1,a2 之间进行一次操作以后,原差值 a2−a1a_2-a_1a2−a1 就变成了 a3−a2,a2−a1a_3-a_2,a_2-a_1a3−a2,a2−a1,即每次操作可以把一个差值分成两份,求最后进行 mmm 次操作以后得到的 n−1+mn-1+mn−1+m 个差值序列中每个数与 LLL 的差的平方和最小是多少。
我们设这 n−1n-1n−1 个差值,第 iii 个差值的值为 sss 分裂 xix_ixi 次。
设 f(s,x)f(s,x)f(s,x) 表示一个数 sss,分裂 xxx 次后产生的最小平方和,根据柯西不等式,显然我们将 sss 平分成 x+1x+1x+1 份是最优的。
因此我们可以得到 :
f(s,x)=(Sx+1−L)2×(x+1)=(s−(x+1)×L)2x+1=s2x+1+2sL+(x+1)×L2\begin{aligned}f(s, x)&=(\cfrac {S}{x+1}-L)^2\times (x+1)&\\&=\cfrac {(s-(x+1)\times L)^2}{x+1}&\\&=\frac {s^2}{x+1}+2sL+(x+1)\times L^ 2 \end{aligned} f(s,x)=(x+1S−L)2×(x+1)=x+1(s−(x+1)×L)2=x+1s2+2sL+(x+1)×L2
根据题意,s∈(−∞,+∞)s\in(-\infin,+\infin)s∈(−∞,+∞),x∈(0,+∞)x\in(0,+\infin)x∈(0,+∞),我们可以对 f(s,x)f(s, x)f(s,x) 进行求导:
df(s,x)dx=L2−s2(x+1)2\cfrac{df(s, x)}{dx}=L^2-\frac {s^2}{(x+1)^2} dxdf(s,x)=L2−(x+1)2s2
无法判断正负,考虑再次求导:
d2f(s,x)dx2=2s2(x+1)3>0\frac {d^2f(s, x)}{dx^2}=\frac{2s^2}{(x+1)^3}>0 dx2d2f(s,x)=(x+1)32s2>0
此时的导数一定是大于 000 的,我们可以得出结论:对于第 iii 个差值,我们增加他的分裂次数 xix_ixi,f(si,xi)f(s_i,x_i)f(si,xi) 的增值 Δi\Delta_iΔi 关于 xix_ixi 是递增的,其中 Δi=f(si,xi+1)−f(si,xi)\Delta_i=f(s_i,x_i+1)-f(s_i,x_i)Δi=f(si,xi+1)−f(si,xi)。
那么问题就可以转化为 有 n−1n-1n−1 个递增序列,从中选出 mmm 个数使他们的和最小,显然可以使用堆贪心取最大差值即可,但是 m≤108m\le 10^8m≤108,堆贪心时间复杂度为 O(mlogn)O(m\log n)O(mlogn),考虑优化。
考虑二分最小偏差值增量 Δi\Delta_iΔi,我们可以直接解方程求出每个数最多能分裂的次数,与能够执行的 mmm 次操作比较大小即可。
BZOJ 2135 刷题计划(贪心,求导,二分)【BZOJ 修复工程】相关推荐
- BZOJ第一页刷题计划
BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...
- LeetCode LCP 12. 小张刷题计划(二分查找)
1. 题目 为了提高自己的代码能力,小张制定了 LeetCode 刷题计划,他选中了 LeetCode 题库中的 n 道题,编号从 0 到 n-1,并计划在 m 天内按照题目编号顺序刷完所有的题目(注 ...
- leetcode每日刷题计划-简单篇day8
leetcode每日刷题计划-简单篇day8 今天是纠结要不要新买手机的一天QAQ想了想还是算了吧,等自己赚钱买,加油 Num 70 爬楼梯 Climbing Stairs class Solutio ...
- 北邮oj题库刷题计划(更新ing)
北邮oj题库刷题计划(更新ing) 83. A + B Problem 84 Single Number 85. Three Points On A Line 120 日期 121 最值问题 122 ...
- 力扣动态规划入门21天刷题计划(共计46题)
刷题地址:https://leetcode-cn.com/study-plan/dynamic-programming/?progress=8e97f6 动态规划常常适用于有重叠子问题和最优子结构性质 ...
- 关于leetcode刷题计划
1.简单题目一天2-3: 2.中等题目一天1-2,: 3.困难题目一天1: ~~~每天刷题数目2-3,并写好总结,题目按tags分类,要cover到每个tag: ~~~每周抽1小时回顾一周得题目: ~ ...
- LeetCode力扣刷题——居合斩!二分查找
二分查找 一.算法解释 二分查找也常被称为二分法或者折半查找,每次查找时通过将待查找区间分成两部分并只取 一部分继续查找,将查找的复杂度大大减少.对于一个长度为 O ( n ) 的数组 ...
- bzoj 刷题计划~_~
bzoj 2818 两个互质的数的gcd=1,所以他们同时乘一个素数那么他们的gcd=这个素数,所以枚举素数p找n/p以内有多少对互质数,用欧拉函数. bzoj 2809 可并堆,对于每一个子树显然是 ...
- 【自我救赎--牛客网Top101 4天刷题计划】 第一天 热身运动
第一天 声明:本系列文章仅适合二刷有经验的算法er学习,以后会出详细的每一题的讲解,这里只是简单的说明思路来帮助大家快速刷完Top101,另外博主的算法全程跟着 labuladong 大佬学习,这里特 ...
最新文章
- SAP WM LT10事务代码的一个坑?
- AngularJS自定义表单验证
- SQLCLR(五)聚合
- GUI菜单——菜单条、菜单、子条目之间关系
- Saltstack基本安装部署
- java扫描指定package注解_java随笔-扫描使用指定注解的类与方法
- Linus系统下查看系统版本
- python技巧(1)--如何转换itertools.chain对象为数组
- 【NOI1998】免费馅饼,膜一膜XYX大爷
- 构建安全应用程序架构必须考虑的十二问
- linux 提取重复数据处理,Linux提取命令cut
- Hot Swap failed:add method not implemented
- 同花顺 行情服务器系统,[分享]完美运行同花顺,Linux下的股友有福了
- 基于文本数据的情感分析系统
- somachine3.1安装包和安装方法
- 决策树模型回归可视化分析_基于Blank Friday商店销售数据分析构建回归模型
- The run destination''''is not valid for Running the scheme
- C语言从一段字符串中提取IP地址的方法
- ensp 防火墙 一对一映射
- 171023 逆向-BDCTF(Re)