zoukankan      html  css  js  c++  java
  • [BZOJ4709][JSOI2011]柠檬(斜率优化DP)

    显然选出的每一段首尾都是相同的,于是直接斜率优化,给每个颜色的数开一个单调栈即可。

     1 #include<cstdio>
     2 #include<vector>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=100010;
    10 ll n,ans,a[N],f[N],lst[N],top[N],cnt[N];
    11 struct P{ ll x,y; };
    12 vector<P>s[N];
    13 
    14 bool Cmp(P a,P b,P c){ return (b.y-a.y)*(c.x-b.x)<=(c.y-b.y)*(b.x-a.x); }
    15 
    16 int main(){
    17     freopen("bzoj4709.in","r",stdin);
    18     freopen("bzoj4709.out","w",stdout);
    19     scanf("%lld",&n);
    20     rep(i,1,n) scanf("%lld",&a[i]),cnt[i]=cnt[lst[a[i]]]+1,lst[a[i]]=i;
    21     rep(i,1,n) if (s[a[i]].size()==0) s[a[i]].push_back((P){0,0});
    22     rep(i,1,n){
    23         int p=a[i]; P tmp=(P){2*p*cnt[i],f[i-1]+p*cnt[i]*cnt[i]-2*p*cnt[i]};
    24         while (top[p]>1 && Cmp(s[p][top[p]-1],s[p][top[p]],tmp)) top[p]--,s[p].pop_back();
    25         top[p]++; s[p].push_back(tmp);
    26         while (top[p]>1 && (s[p][top[p]].x-s[p][top[p]-1].x)*cnt[i]>=s[p][top[p]].y-s[p][top[p]-1].y)
    27             top[p]--,s[p].pop_back();
    28         f[i]=s[p][top[p]].y-s[p][top[p]].x*cnt[i]+p+2*p*cnt[i]+p*cnt[i]*cnt[i]; ans=max(ans,f[i]);
    29     }
    30     printf("%lld
    ",ans);
    31     return 0;
    32 }
  • 相关阅读:
    [luogu3334]抛硬币
    [luogu3706]硬币游戏
    [luogu4548]歌唱王国
    [hdu4652]Dice
    [atAGC013F]Two Faced Cards
    [atAGC045F]Division into Multiples
    [atAGC045E]Fragile Balls
    [atAGC045D]Lamps and Buttons
    [luogu5574]任务分配问题
    [luogu4331]数字序列
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9833920.html
Copyright © 2011-2022 走看看