BZOJ1911 [Apio2010]特别行动队
2016-10-30 22:57
288 查看
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
-1 10 -20
2 2 3 4
正解:DP+斜率优化
解题报告:
朴素DP很好想,就是$${f[i]=max(f[j]+a*(s[i]-s[j])^2+b*(s[i]-s[j])+c) (j<i)}$$
但是只有50分,考虑优化。
因为这个式子一看就很可推,试着证明有没有单调性或者可以弄出斜率...
如果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]}$$
移过去就是$${\frac {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] }$$
(ps:带a的那个式子,就是分母,是小于0的,所以要变号...)
然后维护一个斜率单增的单调队列,相当于是一个下凸的凸包,就ok了。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
Description
Input
Output
Sample Input
4-1 10 -20
2 2 3 4
Sample Output
9HINT
正解:DP+斜率优化
解题报告:
朴素DP很好想,就是$${f[i]=max(f[j]+a*(s[i]-s[j])^2+b*(s[i]-s[j])+c) (j<i)}$$
但是只有50分,考虑优化。
因为这个式子一看就很可推,试着证明有没有单调性或者可以弄出斜率...
如果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]}$$
移过去就是$${\frac {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] }$$
(ps:带a的那个式子,就是分母,是小于0的,所以要变号...)
然后维护一个斜率单增的单调队列,相当于是一个下凸的凸包,就ok了。
1 //It is made by ljh2000 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 using namespace std; 14 typedef long long LL; 15 const int inf = (1<<30); 16 const int MAXN = 1000011; 17 int n; 18 LL a,b,c; 19 LL s[MAXN],f[MAXN]; 20 int dui[MAXN],head,tail; 21 22 inline int getint() 23 { 24 int w=0,q=0; char c=getchar(); 25 while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 26 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w; 27 } 28 inline LL count(int x,int y){ return ( (f[x]-f[y])+a*(s[x]*s[x]-s[y]*s[y])-b*(s[x]-s[y]) )/(a*2*(s[x]-s[y])); } 29 inline void work(){ 30 n=getint(); a=getint(); b=getint(); c=getint(); int x; 31 for(int i=1;i<=n;i++) x=getint(),s[i]=s[i-1]+x; 32 head=tail=1; dui[tail]=0; int from; 33 for(int i=1;i<=n;i++) { 34 while(head<tail && count(dui[head+1],dui[head])<s[i]) head++; 35 from=dui[head]; f[i]=f[from]+a*(s[i]-s[from])*(s[i]-s[from])+b*(s[i]-s[from])+c; 36 while(head<tail && count(dui[tail-1],dui[tail])>count(dui[tail],i)) tail--; 37 dui[++tail]=i; 38 } 39 printf("%lld",f ); 40 } 41 42 int main() 43 { 44 work(); 45 return 0; 46 }
相关文章推荐
- 【BZOJ 1911】 [Apio2010]特别行动队
- bzoj 1911 [Apio2010]特别行动队(斜率优化+DP)
- BZOJ 1911 [Apio2010]特别行动队
- [BZOJ1010][HNOI2008]玩具装箱[BZOJ1911][APIO2010]特别行动队[BZOJ1492][NOI2007]货币兑换 斜率优化
- Bzoj 1911: [Apio2010]特别行动队(斜率优化)
- bzoj 1911: [Apio2010]特别行动队
- 【bzoj1911】[Apio2010]特别行动队
- BZOJ 1911 [APIO2010]特别行动队
- [省选前题目整理][BZOJ 1911][APIO 2010]特别行动队(斜率优化DP)
- bzoj1911[Apio2010] 特别行动队
- 斜率优化专题4——bzoj 1911: [Apio2010] 特别行动队 题解
- bzoj 1911: [Apio2010]特别行动队(斜率优化)
- bzoj 1911: [Apio2010]特别行动队
- bzoj1911 [Apio2010]特别行动队
- BZOJ 1911 [Apio2010]特别行动队(单调队列优化DP)
- 【bzoj1911】【APIO2010】【特别行动队】【斜率优化】
- BZOJ1911 [Apio2010]特别行动队 斜率优化
- bzoj1911: [Apio2010]特别行动队 斜率优化DP
- BZOJ 1911: [Apio2010]特别行动队(斜率优化)
- BZOJ1911 [APIO2010] 特别行动队