• bzoj 1911 [Apio2010]特别行动队(斜率优化+DP)


     

    1911: [Apio2010]特别行动队

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 3191  Solved: 1450
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    4
    -1 10 -20
    2 2 3 4

    Sample Output

    9

    HINT

    Source

    【思路】

           斜率优化。

           设f[i]表示将前i个分组的最优值,则有转移方程式:

                  f[i]=max{ f[j]+a*(C[i]-C[j])^2+b*(C[i]-C[j])+c }

           经过化简得到:

                  f[i]=max{ (f[j]+a*C[j]^2-b*C[j])-2*a*C[i]*C[j] } + a*C[i]^2+b*C[i]+c

           单调队列维护上凸包即可。

    【代码】

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 
     5 typedef long long LL;
     6 const int N = 1000000+10;
     7 struct point { LL x,y;
     8 }q[N],now;
     9 int n,a,b,c,L,R;  LL C[N];
    10 
    11 LL cross(point a,point b,point c) {
    12     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
    13 }
    14 void read(LL& x) {
    15     char c=getchar(); while(!isdigit(c)) c=getchar();
    16     x=0; while(isdigit(c)) x=x*10+c-'0' , c=getchar();
    17 }
    18 int main() {
    19     scanf("%d%d%d%d",&n,&a,&b,&c);
    20     for(int i=1;i<=n;i++)
    21         read(C[i]) , C[i]+=C[i-1];
    22     for(int i=1;i<=n;i++) {
    23         while(L<R && q[L].y-2*a*C[i]*q[L].x <= q[L+1].y-2*a*C[i]*q[L+1].x) L++;
    24         now.x=C[i];
    25         now.y=q[L].y-2*a*C[i]*q[L].x+2*a*C[i]*C[i]+c;
    26         while(L<R && cross(q[R-1],now,q[R])<=0) R--;
    27         q[++R]=now;
    28     }
    29     printf("%lld",q[R].y+b*C[n]-a*C[n]*C[n]);
    30     return 0;
    31 }
  • 相关阅读:
    捡来的一个大数模版。很好用
    小探catlan数
    hdu1060数学题求幂最左边的数
    食物相克
    工作 瓶颈 思路问题
    从用户态open到内核驱动实现
    内核代码 结构
    I2C原理
    asm
    man 2 3 5 普通命令(1) 函数库(3)
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5117768.html
Copyright © 2020-2023  润新知