标签:
嗯……第三道斜率优化的题目了。
定义 $s[i]=\sum_{k=1}^{i} x[k] $
方程:$f[i]=max\{ f[j]+a*(s[i]-s[j])^2+b*(s[i]-s[j])+c \} $
对于 $ j > k $
若决策 j 比 k 更优:\[ \begin{aligned} {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*(s[j]^2-s[k]^2)-b*(s[j]-s[k])} &> {2a*s[i]*(s[j]-s[k])} \\ \frac{ f[j]-f[k]+a*(s[j]^2-s[k]^2)-b*(s[j]-s[k]) } { 2a*(s[j]-s[k]) } &> {s[i]} \end{aligned} \]
1 /************************************************************** 2 Problem: 1911 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:1260 ms 7 Memory:28616 kb 8 ****************************************************************/ 9 10 //BZOJ 1911 11 #include<cmath> 12 #include<vector> 13 #include<cstdio> 14 #include<cstring> 15 #include<cstdlib> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 #define pb push_back 22 using namespace std; 23 int getint(){ 24 int v=0,sign=1; char ch=getchar(); 25 while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();} 26 while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();} 27 return v*=sign; 28 } 29 const int N=1e6+10; 30 typedef long long LL; 31 /******************tamplate*********************/ 32 LL f[N],x[N],s[N]; 33 int q[N],a,b,c; 34 double slop(int k,int j){ 35 return double(f[j]-f[k]+a*(s[j]*s[j]-s[k]*s[k])+b*(s[k]-s[j]))/ 36 double(2*a*(s[j]-s[k])); 37 } 38 int main(){ 39 #ifndef ONLINE_JUDGE 40 freopen("1911.in","r",stdin); 41 freopen("1911.out","w",stdout); 42 #endif 43 int n=getint(); 44 a=getint(),b=getint(),c=getint(); 45 F(i,1,n){ x[i]=getint(); s[i]=s[i-1]+x[i];} 46 int l=0,r=0; 47 F(i,1,n){ 48 while(l<r && slop(q[l],q[l+1])<s[i])l++; 49 int t=q[l]; 50 f[i]=f[t]+a*((s[i]-s[t])*(s[i]-s[t]))+b*(s[i]-s[t])+c; 51 while(l<r && slop(q[r-1],q[r])>slop(q[r],i))r--; 52 q[++r]=i; 53 } 54 printf("%lld\n",f[n]); 55 return 0; 56 }
【BZOJ】【1911】【APIO2010】特别行动队commando
标签:
原文地址:http://www.cnblogs.com/Tunix/p/4332891.html