放一手原题


题解:

第一次写(抄)斜率优化,心里还是有点小激动的。讲一下怎么实现的!

首先我们可以考虑一个朴素的dp:DP[i]表示前i个数字的最少花费,显然我们有一个转移方程

DP[i]=min{DP[j]+M+(sum[i]-sum[j])^2}

但是N^2肯定会超时,我们考虑优化他

假设有k<j<i,如果令j对i的贡献比k好

显然我们有这样的式子

DP[j]+M+(sum[i]-sum[j])^2 < DP[k]+M+(sum[i]-sum[j])^2

把平方打开之后移项

可以得到

 ((DP[j]+sum[j]^2)- (DP[k]+sum[k]^2) )  / 2*(sum[j]-sum[k]) < sum[i]

可以把这个式子看成(yj - yk)/(xj - xk) 这样就得到了一个类似斜率的式子!

有了这些结论有什么用呢?

令G[i,j]表示刚刚的斜率式,依然有k<j<i

当j的决策比k优秀的时候,则满足G[i,j]>G[j,k]

我们可以用单调队列维护解集,利用斜率判断元素的入队和出队,这样可以使时间复杂度降低到O(n)了

#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 500005
using namespace std;
int dp[N],q[N],sum[N],l,r,n,m;
int GetDp(int i,int j)
{
return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);
}
int GetUp(int j,int k)
{
return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]);
}
int GetDown(int j,int k)
{
return *(sum[j]-sum[k]);
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
for (int i=,x;i<=n;i++)
scanf("%d",&x),sum[i]=sum[i-]+x;
l=r=;
q[r++]=;
for (int i=;i<=n;i++)
{
while (l+<r && GetUp(q[l+],q[l])<=sum[i]*GetDown(q[l+],q[l]))
l++;
dp[i]=GetDp(i,q[l]);
while (l+<r && GetUp(i,q[r-])*GetDown(q[r-],q[r-])<=GetUp(q[r-],q[r-])*GetDown(i,q[r-]))
r--;
q[r++]=i;
}
printf("%d\n",dp[n]);
}
return ;
}

斜率优化第一题! HDU3507 | 单调队列优化DP的更多相关文章

  1. 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]

    题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ...

  2. BestCoder Round #89 02单调队列优化dp

    1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01  HDU 5944   水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...

  3. Codeforces 1304F1/F2 Animal Observation(单调队列优化 dp)

    easy 题目链接 & hard 题目链接 给出一张 \(n \times m\) 的矩阵,每个格子上面有一个数,你要在每行选出一个点 \((i,t)\),并覆盖左上角为 \((i,t)\), ...

  4. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

  5. 【刷题笔记】DP优化-单调队列优化

    单调队列优化 眼界极窄的ZZ之前甚至不会单调队列--(好丢人啊) 单调队列优化的常见情景: 转移可以转化成只需要确定一个维度,而且这个维度的取值范围在某个区间里 修剪草坪 这个题学长讲的好像是另外一个 ...

  6. 动态规划专题(四)——单调队列优化DP

    前言 单调队列优化\(DP\)应该还算是比较简单容易理解的吧,像它的升级版斜率优化\(DP\)就显得复杂了许多. 基本式子 单调队列优化\(DP\)的一般式子其实也非常简单: \[f_i=max_{j ...

  7. tyvj1305 最大子序和 【单调队列优化dp】

    描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7 当m=2或m=3时,S=5+1=6 输 ...

  8. P3957 跳房子(二分答案+单调队列优化DP)

    题目链接:https://www.luogu.org/contestnew/show/4468 题目大意:跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则 ...

  9. 【Luogu】P2569股票交易(单调队列优化DP)

    题目链接 首先这题可以肯定的是朴素DP秒出.然后单调队列优化因为没接触过所以不会emmm 而且脑补没补出来 坐等四月省选倒数第一emmm 心态爆炸,偷懒放题解链接 #include<cstdio ...

随机推荐

  1. vim分屏功能总结

    vim的分屏功能 总结起来,基本都是ctrl+w然后加上某一个按键字母,触发一个功能.(1)在shell里打开几个文件并且分屏: vim -On file1 file2 ... vim -on fil ...

  2. php api_token 与 user_token 简析

    前言: --->非开放性平台 --->公司内部产品 接口特点汇总: 1.因为是非开放性的,所以所有的接口都是封闭的,只对公司内部的产品有效: 2.因为是非开放性的,所以OAuth那套协议是 ...

  3. Jmeter接口测试(二)工具介绍

    一.Jmeter文件目录介绍 ◆ bin:可执行文件目录 Bin 目录文件 jmeter.bat:windows 的启动文件 jmeter.log:日志文件 jmeter.sh:linux 的启动文件 ...

  4. 【WXS数据类型】Object

    Object 是一种无序的键值对. 属性: 名称 值类型 说明 [Object].constructor [String] 返回值为“Object”,表示类型的结构字符串 方法: 原型:[Object ...

  5. hdu刷题1

    1002  大数加法 #include<iostream> #include<cstring> using namespace std; int main() { ],b[]; ...

  6. day-16 CNN卷积神经网络算法之Max pooling池化操作学习

    利用CNN卷积神经网络进行训练时,进行完卷积运算,还需要接着进行Max pooling池化操作,目的是在尽量不丢失图像特征前期下,对图像进行downsampling. 首先看下max pooling的 ...

  7. NFC学习总结

    NFC 学习总结 1.NFC 的基本概念 NFC 是 Near FieldCommunication 的缩写,即距离无线通信技术.由飞利浦公司和索尼公司共同开发的NFC 是一种非接触式识别和互联技术, ...

  8. 定点数(fixed-point number)

    定义 定点数(fixed-point number)就是小数点位置固定的数,也就是说,小数点后面的位数是固定的,比如要记录一笔账目,这些账目的数字都不会超过100,就可以使用2位小数位定点数来记录,比 ...

  9. 《C++常见问题及解答》

    一.类 1. 常数据成员的初始化只能在构造函数的初始化列表中进行 2. 静态数据成员不可以在类内初始化 3. 创建一个对象时的构造函数的调用次序:对象成员的构造函数.对象自身的构造函数 4. 创建一个 ...

  10. 软工2017团队协作第七周——个人PSP

    10.27 --11.2本周例行报告 1.PSP(personal software process )个人软件过程. 类型 任务 开始时间                结束时间 中断时间 实际用时 ...