【BZOJ-1911】特别行动队 DP + 斜率优化

1911: [Apio2010]特别行动队

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 3478  Solved: 1586
[Submit][Status][Discuss]

4
-1 10 -20
2 2 3 4

9

Solution

$(dp[j]-dp[i]+a*(pos[j]^2-pos[i]^2)+b*(pos[i]-pos[j]))/(2*a*(pos[j]-pos[i]))$那么维护一下即可

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define maxn 1000100
int n,a,b,c; int po[maxn]; long long pos[maxn],dp[maxn];
int que[maxn],l,r;
long long pf(long long x){return x*x;}
double slope(int i,int j)
{
double fz=dp[j]-dp[i]+a*(pf(pos[j])-pf(pos[i]))+b*(pos[i]-pos[j]);
double fm=(2*a*(pos[j]-pos[i]));
return fz/fm;
}
int main()
{
for (int i=1; i<=n; i++) po[i]=read(),pos[i]=pos[i-1]+po[i];
for (int tmp,i=1; i<=n; i++)
{
while (l<r && slope(que[l],que[l+1])<pos[i]) l++;
tmp=que[l];
dp[i]=dp[tmp]+a*pf(pos[i]-pos[tmp])+b*(pos[i]-pos[tmp])+c;
while (l<r && slope(que[r-1],que[r])>slope(que[r],i)) r--;
que[++r]=i;
}
printf("%lld\n",dp[n]);
return 0;
}

posted @ 2016-04-11 21:41  DaD3zZ  阅读(231)  评论(0编辑  收藏  举报