layout: post

title: 「kuangbin带你飞」专题二十 斜率DP

author: "luowentaoaa"

catalog: true

tags:

mathjax: true

- kuangbin

- 动态规划

- 斜率DP


传送门

A.HDU - 3507 Print Article

题意

就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M

让我们求这个费用的最小值。

题解

概率DP的入门题,把我搞得要死要活的。

首先dp[i]表示输出前i个的最小费用 很简单得得出一个方程

\[dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j])^2\\1<=j<i
\]

其中sum[i]表示数字的前i项和,但是这个方程的复杂度是n^2 所以这时候就要用到斜率优化 ,ps:个人感觉斜率DP都用到了队列,来把前面绝对不优秀的项都出队,这样每次运算都只要在队列中找就行,而且每个元素只有一次出队和入队 所以复杂度只有N

首先假设在算dp[i]的 ,k<j<i,并且J点比K点优秀

那么

\[dp[j]+(sum[i]-sum[j])^2+M<=dp[k]+(sum[i]-sum[k])^2+M
\]

对上面方程分解整理得:

\[[(dp[j]+sum[j]^2)-(dp[k]+sum[k]^2)]÷2(sum[j]-sum[k])<=sum[i]
\]

注意正负号,不然会影响不等号的方向

\[Y(x)=dp[x]+sum[j]^2\\X(x)=2×sum[j]
\]

于是上面的式子变成斜率表达式

\[[Y(j)-Y(k)]/[X(j)-X(k)]<=sum[i]
\]

由于不等式右边的sum[i]随着i的增加而递增

所以我们另

\[g[j,k]=[Y(j)-Y(k)]/[X(j)-X(k)]
\]

1.如果上面的不等式成立 说明J比K优,而且随着i的增加上述不等式一定是成立的,也就是对于以后的i来说J都比K优秀,所以K是可以淘汰的

2.如果

\[g[J,K]>g[I,J]\\k<j<i
\]

那么J是可以淘汰的

假设g[I,J]<sum[i] 就是I比J优秀,那么J就没存在的价值

相反,如果g[I,J]>sum[i] 那么同样有g[J,K]>sum[I] 那么K比J优秀 所以J是可以淘汰的

所以这样相当于维护一个下凸的图形,斜率在增加,用队列维护

ps:以上都是抄bin巨的博客

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pp pair<int,int>
const ll mod=998244353;
const int maxn=5e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int gcd(int a,int b){while(b){int t=a%b;a=b;b=t;}return a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
int dp[maxn];
int sum[maxn];
int a[maxn];
int q[maxn];
int m,n;
int head,tail;
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 2*(sum[j]-sum[k]);
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
while(cin>>n>>m){
for(int i=1;i<=n;i++)cin>>a[i];
memset(sum,0,sizeof(sum));
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
head=tail=0;
q[tail++]=0;
for(int i=1;i<=n;i++){
while(head+1<tail&&getUP(q[head+1],q[head])<=sum[i]*getDOWN(q[head+1],q[head]))
head++;
dp[i]=getDP(i,q[head]);
while(head+1<tail&&getUP(i,q[tail-1])*getDOWN(q[tail-1],q[tail-2])<=getUP(q[tail-1],q[tail-2])*getDOWN(i,q[tail-1]))
tail--;
q[tail++]=i;
}
cout<<dp[n]<<endl;
}
return 0;
}

「kuangbin带你飞」专题二十 斜率DP的更多相关文章

  1. 「kuangbin带你飞」专题二十二 区间DP

    layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...

  2. 「kuangbin带你飞」专题十二 基础DP

    layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...

  3. 「kuangbin带你飞」专题十九 矩阵

    layout: post title: 「kuangbin带你飞」专题十九 矩阵 author: "luowentaoaa" catalog: true tags: mathjax ...

  4. 「kuangbin带你飞」专题十八 后缀数组

    layout: post title: 「kuangbin带你飞」专题十八 后缀数组 author: "luowentaoaa" catalog: true tags: - kua ...

  5. 「kuangbin带你飞」专题十四 数论基础

    layout: post title: 「kuangbin带你飞」专题十四 数论基础 author: "luowentaoaa" catalog: true tags: mathj ...

  6. 「kuangbin带你飞」专题十七 AC自动机

    layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...

  7. 「kuangbin带你飞」专题十五 数位DP

    传送门 A.CodeForces - 55D Beautiful numbers 题意 一个正整数是 漂亮数 ,当且仅当它能够被自身的各非零数字整除.我们不必与之争辩,只需计算给定范围中有多少个漂亮数 ...

  8. [kuangbin带你飞]专题二十 斜率DP

            ID Origin Title   20 / 60 Problem A HDU 3507 Print Article   13 / 19 Problem B HDU 2829 Lawr ...

  9. kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数

    第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一 ...

随机推荐

  1. 就算WORD高手也无法解释的Word的一些疑惑.,一些已经解决,一些没有解决

    如下功能如何用? 1.选项->保存->显示其他保存位置(即使可能需要登录)? 解答:您能告诉我吗? 2.字体->为字体调整字间距? 解答:自动调整某些字符之前的距离,使得更加美观.例 ...

  2. install ironic-inspector

    安装相应的包和组件 yum install openstack-ironic-inspector python-ironic-inspector-client -y 创建user openstack ...

  3. Leetcode 670.最大交换

    最大交换 给定一个非负整数,你至多可以交换一次数字中的任意两位.返回你能得到的最大值. 示例 1 : 输入: 2736 输出: 7236 解释: 交换数字2和数字7. 示例 2 : 输入: 9973 ...

  4. C++寒假学习计划

    课程 中国大学mooc西北工业大学c++程序设计 理由 本课程有48节,章节分类清晰,由许多小知识块组成,条例清晰便于学习,由基础开始,由浅入深,适合我这种小白. 计划 从2.8号至2.28除去2.1 ...

  5. chrome浏览器console拓展用法

    chrome 浏览器console打印 使用CSS美化输出信息 console.log("%cThis will be formatted with large, blue text&quo ...

  6. python3.6操作mysql

    1.通过 pip 安装 pymysql 进入 cmd  输入  pip install pymysql   回车等待安装完成: 安装完成后出现如图相关信息,表示安装成功. 2.测试连接 import ...

  7. nagios客户端安装

    在被监控服务器(Linux/unix)上安装Nagios-plugins和nrpe 1.添加用户   1 2 ; html-script: false ]/usr/sbin/useradd -m na ...

  8. 根文件系统制作、NFS配置与安装及利用NFS挂载根文件系统

    最近打算从头开始制作根文件系统,下面是开发过程. 一.根文件系统的制作 0.FHS(Filesystem Hierarchy Standard)标准介绍 该标准规定了根目录下各个子目录的名称及其存放的 ...

  9. JS XMLHttpRequest.upload.addEventListener 传参,回调

    JS 回调函数,传参的办法. function uploadFile(t) { var fd = new FormData(); fd.append("_netLogo", doc ...

  10. swf自动播放时如何全屏全部显示

    在QQ Show里面看到一个很可爱的挂件,很想把它弄下来.弄下来的方法很简单,直接去网页缓存文件里面找.找到了之后,按下面的方法插入到网页中: 1 <object height="10 ...