zoukankan      html  css  js  c++  java
  • 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队

    【题目描述】

    n个数,分成连续的若干段,每段的分数为a*x^2+b*x+cabc是给出的常数),其中x为该段的各个数的和。求如何分才能使得各个段的分数的总和最大。

    【输入格式】 

    1:1整数N (1 <= N <= 1000000)

    2行:3个整数abc-5<=a<=-1,|b|<=10000000,|c|<=10000000

    下来N个整数,每个数的范围为[1,100]

    【输出格式】 

        一个整数,各段分数总和的值最大

    【分析】

      设s[i]为i的前缀和。

      dp方程: f[i]=f[j]+a*(s[i]-s[j])^2+b(s[i]-s[j])+c

      即 f[i]=-2a*s[i]*s[j]+a*s[j]^2-b*s[j]+f[j]+a*s[i]^2+b*s[i]+c

      化成斜率优化标准形式,维护一个右上凸包即可。

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cmath>
     8 using namespace std;
     9 #define Maxn 1000010
    10 #define LL long long
    11 
    12 LL w[Maxn],s[Maxn];
    13 LL a,b,c;
    14 
    15 struct node
    16 {
    17     LL x,y;
    18 }t[Maxn];int len=0;
    19 
    20 LL f[Maxn];
    21 
    22 bool check(int x,int y,int k)
    23 {
    24     LL kk=k;
    25     return kk*(t[y].x-t[x].x)<=(t[y].y-t[x].y);
    26 }
    27 
    28 bool check2(int x,int y,int z)
    29 {
    30     return (t[z].x-t[y].x)*(t[y].y-t[x].y)<=(t[y].x-t[x].x)*(t[z].y-t[y].y);
    31 }
    32 
    33 int main()
    34 {
    35     int n;
    36     scanf("%d",&n);
    37     scanf("%lld%lld%lld",&a,&b,&c);
    38     s[0]=0;
    39     for(int i=1;i<=n;i++)
    40     {
    41         scanf("%lld",&w[i]);
    42         s[i]=s[i-1]+w[i];
    43     }
    44     int st;
    45     t[++len].x=0;t[len].y=0;st=1;
    46     for(int i=1;i<=n;i++)
    47     {
    48         while(st<len&&check(st,st+1,2*a*s[i])) st++;
    49         f[i]=-2*a*s[i]*t[st].x+t[st].y+a*s[i]*s[i]+b*s[i]+c;
    50         t[0].x=s[i];t[0].y=a*s[i]*s[i]-b*s[i]+f[i];
    51         while(st<len&&check2(len-1,len,0)) len--;
    52         t[++len]=t[0];
    53     }
    54     printf("%lld
    ",f[n]);
    55     return 0;
    56 }
    [BZOJ 1911]

    2016-09-19 20:45:07

  • 相关阅读:
    写代码如坐禅:你是哪一类程序员
    关于鸿蒙的商业讨论
    为什么你总是“把天聊死”?
    生活不易,唯有努力
    如何用一句话激怒一名程序员?
    华为正式开源方舟编译器,开源了,它真的开源了!
    为什么HTTPS比HTTP更安全?
    《管理者必读12篇》购买方法
    程序员都在用的电脑小技巧,看一遍就学会,每天早下班一小时
    一位程序员的一天工作清单:5:30下班,5:30起床
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5886555.html
Copyright © 2011-2022 走看看