HDU3507 Print Article(斜率优化+单调队列)
Posted gzr2018
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU3507 Print Article(斜率优化+单调队列)相关的知识,希望对你有一定的参考价值。
大佬的斜率优化博客,写的很好
https://www.cnblogs.com/orzzz/p/7885971.html
DP的斜率优化同四边形优化和数据结构优化类似,都是用一种方法快速找到最优的状态转移,以到达优化的目的。一次O(n)转移可以变成log或者常数级别的。
这个题斜率优化的步骤就是,比较不同的状态转移,写成斜率的形式,发现他们存在一个关系,只需要维护一个下凸的凸包结构,最优状态转移的点一定在这个凸包上,剔除了很多不可能是最优的状态转移点。这个题还存在一个单调性,维护单调队列即可,因为每次找到最优点前面的点都可在凸包上剔除。
这个题算斜率优化的模板,思路推导就见上面的博客吧,我也不会搞LaTeX。
1A代码:
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=5e5+10; ll dp[N]; ll a[N]; ll pre[N]; ll que[N]; int n,m; ll get_up(int i,int j) return dp[j]+pre[j]*pre[j]-dp[i]-pre[i]*pre[i]; ll get_down(int i,int j) return pre[j]-pre[i]; int main() while(~scanf("%d%d",&n,&m)) pre[0]=0; for(int i=1;i<=n;i++) scanf("%lld",&a[i]); pre[i]=pre[i-1]+a[i]; int head=0,tail=0; que[tail]=0; for(int i=1;i<=n;i++) while(head<tail&&get_up(que[head],que[head+1])<=2*pre[i]*get_down(que[head],que[head+1])) head++; //找到一个最优的转移,时间复杂度为为常数,保证队列非空 dp[i]=dp[que[head]]+(pre[i]-pre[que[head]])*(pre[i]-pre[que[head]])+m; while(head<tail&&get_up(que[tail],i)*get_down(que[tail-1],que[tail])<=get_up(que[tail-1],que[tail])*get_down(que[tail],i)) tail--; que[++tail]=i; cout<<dp[n]<<endl; return 0;
以上是关于HDU3507 Print Article(斜率优化+单调队列)的主要内容,如果未能解决你的问题,请参考以下文章
DP(斜率优化):HDU 3507 Print Article
HDU 3507 Print Article(斜率DP优化)