斜率优化第一题! HDU3507 | 单调队列优化DP
放一手原题
题解:
第一次写(抄)斜率优化,心里还是有点小激动的。讲一下怎么实现的!
首先我们可以考虑一个朴素的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的更多相关文章
- 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]
题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ...
- BestCoder Round #89 02单调队列优化dp
1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01 HDU 5944 水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...
- Codeforces 1304F1/F2 Animal Observation(单调队列优化 dp)
easy 题目链接 & hard 题目链接 给出一张 \(n \times m\) 的矩阵,每个格子上面有一个数,你要在每行选出一个点 \((i,t)\),并覆盖左上角为 \((i,t)\), ...
- [小明打联盟][斜率/单调队列 优化dp][背包]
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
- 【刷题笔记】DP优化-单调队列优化
单调队列优化 眼界极窄的ZZ之前甚至不会单调队列--(好丢人啊) 单调队列优化的常见情景: 转移可以转化成只需要确定一个维度,而且这个维度的取值范围在某个区间里 修剪草坪 这个题学长讲的好像是另外一个 ...
- 动态规划专题(四)——单调队列优化DP
前言 单调队列优化\(DP\)应该还算是比较简单容易理解的吧,像它的升级版斜率优化\(DP\)就显得复杂了许多. 基本式子 单调队列优化\(DP\)的一般式子其实也非常简单: \[f_i=max_{j ...
- 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 输 ...
- P3957 跳房子(二分答案+单调队列优化DP)
题目链接:https://www.luogu.org/contestnew/show/4468 题目大意:跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则 ...
- 【Luogu】P2569股票交易(单调队列优化DP)
题目链接 首先这题可以肯定的是朴素DP秒出.然后单调队列优化因为没接触过所以不会emmm 而且脑补没补出来 坐等四月省选倒数第一emmm 心态爆炸,偷懒放题解链接 #include<cstdio ...
随机推荐
- 「国庆训练&知识学习」图的最大独立集与拓展(Land of Farms,HDU-5556)
题意 一个\(N*M\)的矩阵,其中"."代表空地,"0-9"代表古代建筑,我们如果选择了一个编号的古代建筑想要建立,那么对应就要将全部该编号的建筑建立起来,如 ...
- 【template、import、include】微信小程序:模板(template)、引用(import、include)说明
模板(template): 定义模板 <template name="[String]"> <!-- 模板代码 --> <view> <t ...
- lintcode407 加一
加一 给定一个非负数,表示一个数字数组,在该数的基础上+1,返回一个新的数组. 该数字按照大小进行排列,最大的数在列表的最前面. 您在真实的面试中是否遇到过这个题? Yes 样例 给定 [1,2,3] ...
- 在github上面创建属于自己的个性主页
圈子里面越来越多的同事在github上面创建自己的项目文档,那里确实高手云集,海内外的技术大牛小牛们都在那儿有一席之地,为“helloword”贡献自己. 以上感慨略过... 这几日正想创建一个自己的 ...
- JavaScript 作用域链范例
函数在执行的过程中,先从自己内部找变量 如果找不到,再从创建当前函数所在的作用域去找,以此往上 注意找的是变量的当前状态 范例 例1 var a=1 function fn1() { function ...
- Multi-task Correlation Particle Filter for Robust Object Tracking--论文随笔
摘要:在这篇论文中,作者提出一种鲁棒视觉跟踪的多任务相关粒子滤波琪跟踪算法(MCPF).作者首先向我们展示了多任务相关滤波器,该滤波器在训练滤波器模板的时候可以学习不同特征之间的联系.本文提出的MCP ...
- 一个简单的Spring的AOP例子
目标对象的接口:IStudent.java 1 /** 2 * 3 */ 4 package com.dragon.study; 5 6 /** 7 * @author ...
- 2.重新安装CM服务
步骤1.停止CM服务2.删除CM服务3.添加CM服务4.测试数据库 步骤 1.停止CM服务 2.删除CM服务 没有发现可以单独删除某一项CM服务,必须全部删除 3.添加CM服务 4.测试数据库 如果报 ...
- 软工1816 · Alpha冲刺(2/10)
团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 与前后端敲定接口设计的细节 重新理清业务逻辑,对项目最初的设想进行一定修正 跟 ...
- LintCode-68.二叉树的后序遍历
二叉树的后序遍历 给出一棵二叉树,返回其节点值的后序遍历. 样例 给出一棵二叉树 {1,#,2,3}, 返回 [3,2,1] 挑战 你能使用非递归实现么? 标签 递归 二叉树 二叉树遍历 code / ...