APIO2010 特别行动队 & 斜率优化DP入门讲解

做完此题之后 自己应该算是真正理解了斜率优化DP

根据状态转移方程f[i]=max(f[j]+ax^2+bx+c),x=sum[i]-sum[j]

可以变形为 f[i]=max((a*sum[j]^2-b*sum[j])-(2a*sum[j]*sum[i]))+(a*sum[i]^2+b*sum[i]+c)

我们可以把每个决策映射到平面上的一个点

其中x坐标为(a*sum[j]^2-b*sum[j])代表此决策的固定价值(与转移到哪无关)

y坐标为-(2a*sum[j]) 代表此决策的潜在价值(与转移到哪有关)

这样我们就可以开始用单调队列维护一个x递增 y递减的凸壳

------------------------------------------------------------------------

对于每次加入进来的一个新元素

我们先对队首的两个决策进行判断 若某决策现有价值不如后面的决策则将其删去

(因为维护的单调队列中的决策潜在价值是递增的)

然后更新新加的元素的最大值

再对新加元素与队尾的两个决策间进行判断

如果队尾第一个的决策在新加决策和前面所有决策所构成凸壳之内

那么这个决策永远不可能同时优于前一个决策和新加决策 所以就直接删掉就好了

最后将新加的决策加入单调队列

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define rep(i,n) for(int i=1;i<=n;++i)
#define imax(x,y) (x>y?x:y)
#define imin(x,y) (x<y?x:y)
using namespace std;
const int N=1000010;
int sum[N],q[N];
long long f[N];
int n;
long long a,b,c;
long long solve(int x,int y)
{
    return f[x]+a*(sum[y]-sum[x])*(sum[y]-sum[x])+b*(sum[y]-sum[x])+c;
}
long long solvex(int x)
{
    return f[x]+a*sum[x]*sum[x]-b*sum[x];
}
bool judge(int x,int y,int z)
{
    long long tx=solvex(x),ty=solvex(y),tz=solvex(z);
    return (ty-tx)*(sum[z]-sum[x])<=(tz-tx)*(sum[y]-sum[x]);//约掉了-2a
}
int main()
{
    scanf("%d",&n);
    scanf("%lld%lld%lld",&a,&b,&c);
    rep(i,n)
    {
        scanf("%d",&sum[i]);
        sum[i]+=sum[i-1];
    }
    int ifront=1,itail=1;
    q[1]=0;
    rep(i,n)
    {
        while(ifront<itail&&solve(q[ifront],i)<=solve(q[ifront+1],i))
            ++ifront;
        f[i]=solve(q[ifront],i);
        while(ifront<itail&&judge(q[itail-1],q[itail],i))
            --itail;
        q[++itail]=i;
    }
    printf("%lld",f[n]);
    return 0;
}
时间: 2024-10-10 07:42:19

APIO2010 特别行动队 & 斜率优化DP入门讲解的相关文章

【BZOJ1911】[Apio2010]特别行动队 斜率优化DP

想了好久啊.... 用了我感觉比较好写的一种(因为没写过维护凸包),另一种是维护凸包的做法,本质一样?推荐http://www.mamicode.com/info-detail-345781.html. 网上的大多数解法: DP:f[i]=max(f[j]+a*(sum[i]-sum[j])^2+b(sum[i]-sum[j])+c) 显然复杂度不对. 那么假设j>k且f[j]优于f[k] f[j]-f[k]+a*(sum[j]^2-sum[k]^2)-b*(sum[j]-sum[k])>2*

[APIO2010]特别行动队 --- 斜率优化DP

[APIO2010]特别行动队 题面很直白,就不放了. 太套路了,做起来没点感觉了. \(dp(i)=dp(j)+a*(s(i)-s(j))^{2}+b*(s(i)-s(j))+c\) 直接推出一个斜率优化的式子上单调队列就好了 时间/空间复杂度:\(O(n)\) #include<cstdio> #define sid 1000500 #define ri register int #define ll long long #define dd double using namespace

bzoj1911[Apio2010]特别行动队 斜率优化dp

1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 5057  Solved: 2492[Submit][Status][Discuss] Description Input Output Sample Input 4 -1 10 -20 2 2 3 4 Sample Output 9 HINT dp[i]=dp[j]+a*x*x+b*x+cx=sum[i]-sum[j] 证明单调性假设对于i点 k<j且j的决策

BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]

1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 4142  Solved: 1964[Submit][Status][Discuss] Description Input Output Sample Input 4 -1 10 -20 2 2 3 4 Sample Output 9 HINT f[i]=max{f[j]+...} 随便一化就好了 (a*(s[k]*s[k]-s[j]*s[j])+f[k]-f[

BZOJ 1911 特别行动队(斜率优化DP)

应该可以看出这是个很normal的斜率优化式子.推出公式搞一搞即可. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <set>

APIO 2010 特别行动队 | 斜率优化DP

luogu 3628 si表示序列的前缀和f(i)表示将序列的前i个划分若干段的最大价值f(i)= max{f(j)+a∗(si−sj)2+b∗(si−sj)+c},1≤j<i    = max{−2a*sj*si+f(j)+a*sj*sj−b*sj}+a*si*si+b*si+c,1≤j<i 1 #include <cstdio> 2 #include <string> 3 4 typedef long long ll; 5 6 ll a, b, c; 7 8 ll

hdu 2993 MAX Average Problem (斜率优化dp入门)

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5855    Accepted Submission(s): 1456 Problem Description Consider a simple sequence which only contains positive integers as

hdu3507之斜率优化DP入门

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 4780    Accepted Submission(s): 1437 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu

hdu3507 Print Article[斜率优化dp入门题]

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 11761    Accepted Submission(s): 3586 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu