码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 1911] 特别行动队

时间:2018-05-18 23:31:02      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:sky   决定   using   const   namespace   二分   inline   htm   转移   

Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1911

 

Algorithm:

DP方程:dp[i]=max(dp[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c)

方程是显然的,但复杂度为O(N^2),需要优化到O(N),这时就需要斜率优化了

 

推荐博客:https://www.cnblogs.com/MashiroSky/p/6009685.html

这篇博客清晰地从“数”到“形”展现了斜率优化

 

其中必要的前提:dp数组是要具有决策单调性的(即如果在dp[i]下决策j好于k,那么在大于i时j永远要好于k)

同时与i相关的数组具有单调性(不具有决定性,可以通过凸包二分来解决非单调性问题

 

此题符合这几个前提,

如果j>k且j比k更优 :(由决策单调性推出)

dp[j]-dp[k]+a*sum[j]^2-a*sum[k]^2+b*(sum[k]-sum[j])>2*a*(sum[j]-sum[k])*sum[i]

SLOPE(j,k)=(dp[j]-dp[k]+a*sum[j]^2-a*sum[k]^2+b*(sum[k]-sum[j]))  /  (2*a*(sum[j]-sum[k]))>sum[i]

 

用单调队列维护SLOPE

1、使SLOPE(cur,cur+1)保持递增,因为sum[i]递增

2、由于SLOPE(j,k) > sum[i] 时决策j比k更优,因此决策head>head+1>……tail

每次将SLOPE(head,head+1) < sum[i]的head踢出队列,之后的queue[head]即为最优决策

 

记住,SLOPE只是用于判断在sum[i]时j比k优的结论是否成立,我们用优先队列来优化维护其的复杂度

SLOPE(j,k)和SLOPE(j‘‘ ,  k‘‘)间的大小关系与决策的优越性不具有直接联系

 

Code:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN=1e6+10;

ll pre[MAXN],dp[MAXN],que[MAXN],l,r,a,b,c,n;

inline ll read()
{
    char ch;ll num,f=0;
    while(!isdigit(ch=getchar())) f|=(ch==-);
    num=ch-0;
    while(isdigit(ch=getchar())) num=num*10+ch-0;
    return f?-num:num;
}

ll sqr(ll x){return x*x;}

inline double slope(int x,int y)
{
    return (double)(dp[x]-dp[y]+a*sqr(pre[x])-a*sqr(pre[y])+b*(pre[y]-pre[x]))/(double)(2*a*(pre[x]-pre[y]));
}

int main()
{
    n=read();a=read();b=read();c=read();
    for(int i=1;i<=n;i++) pre[i]=read(),pre[i]+=pre[i-1];
    
    for(int i=1;i<=n;i++)
    {
        while(l<r && slope(que[l],que[l+1])<=pre[i]) l++;
        dp[i]=dp[que[l]]+a*sqr(pre[i]-pre[que[l]])+b*(pre[i]-pre[que[l]])+c;
        while(l<r && slope(que[r],i)<=slope(que[r-1],que[r])) r--;
        que[++r]=i;
    }
    cout << dp[n];
    
    return 0;
}

 

Review:

1、如果转移方程显而易见,但要优化复杂度

只要其具有决策单调性,且可由其推出的式子发现与i相关的量可看成斜率  /  转移方程中的dp[i]可看作截距

均可使用斜率优化

 

2、当与i相关的数组不具有单调性时,要利用二分/三分法找到对应斜率(Updating)

[BZOJ 1911] 特别行动队

标签:sky   决定   using   const   namespace   二分   inline   htm   转移   

原文地址:https://www.cnblogs.com/newera/p/9058356.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!