bzoj1911: [Apio2010]特别行动队

Posted Nico&11101001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1911: [Apio2010]特别行动队相关的知识,希望对你有一定的参考价值。

题目链接

bzoj1911: [Apio2010]特别行动队

题解

首先,状态转移方程
\\(f_i = max(f_j+A(S_i-S_j)^2+B(S_i-S_j)+C)\\)
在这里总结一下推斜率优化的两种方法吧

直接推呀:

\\(j<k\\)\\(j\\)\\(k\\)优。

\\[f_j+A(S_i-S_j)^2+B(S_i-S_j)+C>f_k+A(S_i-S_k)^2+B(S_i-S_k)+C \\]

\\[f_j-f_k+A(2S_i-S_j-S_k)*(S_k-S_j)+B(S_k-S_j)>0 \\]

\\[f_j+S_j^2-2AS_iS_j-BS_j >f_k+S_k^2-2AS_iS_k-BS_k \\]

\\(G_j=f_j+AS_j^2-BS_j\\),\\(H_j=-2AS_j\\)
得到
\\(\\frac{G_j-G_k}{H_j-H_k}<-S_i\\)

找直线解析式

代码

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
#define LL long long
inline LL read() { 
    LL x = 0,f = 1;
    char c = getchar(); 
    while(c < \'0\' || c > \'9\'){ if(c == \'-\')f = -1; c = getchar();}  
    while(c <= \'9\' && c >= \'0\')x = x * 10 + c - \'0\',c = getchar(); 
    return x * f; 
} 

const int maxn = 1000007;
LL n,a,b,c; 
LL sum[maxn]; 
LL dp[maxn];  
LL Y (int i) { return dp[i] + a * sum[i] * sum[i] - b * sum[i]; } 
LL X (int i) { return  sum[i]; } 
double slop(int i,int j)  { return 1.0 * (Y(i) - Y(j)) / (X(i) - X(j));  }  
int q[maxn]; 
int main() { 
    n = read(),a = read(),b = read(),c = read(); 
    for(int i = 1;i <= n;++ i) sum[i] = read() + sum[i - 1]; 
    for(int l = 0,r = 0,i = 1;i <= n;++ i)  { 
        while(l < r && slop(q[l],q[l + 1]) > 2 * a * sum[i])l ++; 
           	//dp[i] = dp[q[l]] + a * (sum[i] - sum[q[l]]) * (sum[i] - sum[q[l]]) + b * (sum[i] - sum[q[l]] + c); 
        dp[i] = -(2 * a * sum[i] * X(q[l]) - Y(q[l]) - a * sum[i] * sum[i] - b * sum[i] - c); 
        while(l < r && slop(q[r - 1],q[r]) <= slop(q[r],i)) r --; 
        q[++ r] = i; 	
    } 
    printf("%lld\\n",dp[n]); 
    return 0; 
}


以上是关于bzoj1911: [Apio2010]特别行动队的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1911: [Apio2010]特别行动队

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

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

bzoj 1911: [Apio2010]特别行动队

BZOJ 1911 [Apio2010]特别行动队

bzoj1911: [Apio2010]特别行动队