【bzoj1911】[Apio2010]特别行动队commando
2014年5月18日3,1920
Description
Input
Output
Sample Input
4
-1 10 -20
2 2 3 4
Sample Output
9
HINT
题解
我发现似乎掌握了特殊的斜率优化技巧,我会假装四处看风景
dp方程:f[i]=max(f[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c)
如果j>k且j比k更优
f[j]-f[k]+a*sum[j]^2-a*sum[k]^2+b*(sum[k]-sum[j])>2*a*(sum[j]-sum[k])*sum[i]
转引自hzw的blog,太懒了,什么都没剩下,这道题还是普普通通的斜率优化裸题
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #define ll long long 7 8 using namespace std; 9 10 const int NN=1e6+7; 11 12 int n,l,r; 13 int a,b,c; 14 int x[NN],q[NN]; 15 ll sum[NN],f[NN]; 16 17 ll sqr(ll x) 18 { 19 return x*x; 20 } 21 double slop(int k,int j) 22 { 23 return (double)(f[j]-f[k]+a*(sqr(sum[j])-sqr(sum[k]))+b*(sum[k]-sum[j]))/(double)(2*a*(sum[j]-sum[k])); 24 } 25 int main() 26 { 27 scanf("%d%d%d%d",&n,&a,&b,&c); 28 for(int i=1;i<=n;i++) 29 { 30 scanf("%d",&x[i]); 31 sum[i]=sum[i-1]+x[i]; 32 } 33 for(int i=1;i<=n;i++) 34 { 35 while(l<r&&slop(q[l],q[l+1])<sum[i]) l++;//因为a<0我去 36 int t=q[l]; 37 f[i]=f[t]+a*sqr(sum[i]-sum[t])+b*(sum[i]-sum[t])+c; 38 while(l<r&&slop(q[r-1],q[r])>slop(q[r],i)) r--; 39 q[++r]=i; 40 } 41 printf("%lld",f[n]); 42 }
时间: 2024-10-09 02:03:17