zoukankan      html  css  js  c++  java
  • BZOJ 1911 (特别行动队)

    题意:给定一个数列,将其分成若干段,若某段的和为x则这段的价值为a*x*x+b*x+c。求一种分法使得总价值最大

    f[i]为到第i个时的最大价值,

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

    若j1<j2且j2更优

    f[j1]+a*sum[i]^2+a*sum[j1]^2-2*a*sum[i]*sum[j1]+b*sum[i]-b*sum[j1]+c<f[j2]+a*sum[i]^2+a*sum[j2]^2-2*a*sum[i]*sum[j2]+b*sum[i]-b*sum[j2]+c

    最终化简得到

    f[j1]-f[j2]+a*sum[j1]^2-a*sum[j2]^2-b*sum[j1]+b*sum[j2]<2*a*sum[i]*(sum[j1]-sum[j2])

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<string>
     6 #include<algorithm>
     7 int n;
     8 long long sum[1000005],a,b,c,x,q[1000005],f[1000005];
     9 long long sqr(long long x){
    10     return x*x;
    11 }
    12 double slope(int k,int j){
    13     return double((f[j]-f[k])+a*sqr(sum[j])-a*sqr(sum[k])+b*(sum[k]-sum[j]))/(2*a*(sum[j]-sum[k]));
    14 }
    15 
    16 int main(){
    17     scanf("%d",&n);
    18     scanf("%lld%lld%lld",&a,&b,&c);
    19     sum[0]=0;
    20     for (int i=1;i<=n;i++){
    21         scanf("%lld",&x);
    22         sum[i]=sum[i-1]+x;
    23     }
    24     int l=0,r=0;
    25     for (int i=1;i<=n;i++){
    26         while (l<r&&slope(q[l],q[l+1])<sum[i]) l++;
    27         int t=q[l];
    28         f[i]=f[t]+a*(sum[i]-sum[t])*(sum[i]-sum[t])+b*(sum[i]-sum[t])+c;
    29         while (l<r&&slope(q[r-1],q[r])>slope(q[r],i)) r--;
    30         q[++r]=i;
    31     }
    32     printf("%lld",f[n]);
    33 }
  • 相关阅读:
    Mongodb 的ORM框架 Morphia之注解
    Redis主从集群及哨兵模式
    Dubbo
    Zookeeper
    使用Dockerfile自定义一个包含centos,tomcat的镜像
    linux/centOS 下安装 ngnix
    Session共享
    Linux安装jdk.18和tomcat8
    MongoDB集群的搭建
    多态--方法重写的三个要点
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5553634.html
Copyright © 2011-2022 走看看