zoukankan      html  css  js  c++  java
  • [Sdoi2016]征途

    4518: [Sdoi2016]征途

    Time Limit: 10 Sec  Memory Limit: 256 MB
    [Submit][Status][Discuss]

    Description

    Pine开始了从S地到T地的征途。
    从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站。
    Pine计划用m天到达T地。除第m天外,每一天晚上Pine都必须在休息站过夜。所以,一段路必须在同一天中走完。
    Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小。
    帮助Pine求出最小方差是多少。
    设方差是v,可以证明,v×m^2是一个整数。为了避免精度误差,输出结果时输出v×m^2。
     

    Input

    第一行两个数 n、m。
    第二行 n 个数,表示 n 段路的长度
     

    Output

     一个数,最小方差乘以 m^2 后的值

     

    Sample Input

    5 2
    1 2 5 8 6

    Sample Output

    36

    HINT

    1≤n≤3000,保证从 S 到 T 的总路程不超过 30000

    x[i]表示第i天走的距离,X表示x[i]的平均值=(x[1]+x[2]+……x[m])/m

    m^2 中把1个m 和 算方差的 除m 抵消

    ans=min 【(X-x[1])^2 + (X-x[2])^2 + ……(X- x[m])^2 】*m

          = m*【m*X^2 + (x[1]^2+x[2]^2+……x[m]^2) - 2*X*(x[1]+x[2]+……x[m])】

          = m*(x[1]^2+x[2]^2+……x[m]^2)- (x[1]+x[2]+……x[m])^2

    只需要DP维护 (x[1]^2+x[2]^2+……x[m]^2)的最小值即可

    斜率优化

    #include<cstdio>
    #include<algorithm>
    #define N 3001
    using namespace std;
    int a[N];
    long long sum[N],now[N],last[N];
    int q[N],head,tail;
    long long up(int k,int j)
    {
        return last[j]-last[k]+sum[j]*sum[j]-sum[k]*sum[k];
    }
    long long down(int k,int j)
    {
        return 2*(sum[j]-sum[k]);
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        for(int i=1;i<=n;i++) last[i]=sum[i]*sum[i];
        for(int k=2;k<=m;k++)
        {
            head=tail=1; q[1]=k-1;
            for(int i=k;i<=n;i++)
            {
                while(head<tail && up(q[head],q[head+1])<=down(q[head],q[head+1])*sum[i]) head++;
                now[i]=last[q[head]]+(sum[i]-sum[q[head]])*(sum[i]-sum[q[head]]);
                while(head<tail && up(q[tail-1],q[tail])*down(q[tail],i)>=up(q[tail],i)*down(q[tail-1],q[tail])) tail--;
                q[++tail]=i;
            } 
            swap(now,last);
        }
        printf("%lld",m*last[n]-sum[n]*sum[n]);
    }
  • 相关阅读:
    OSI参考模型(转)
    H3C交换机配置常用命令(转)
    H3C交换机配置学习随笔
    [Swust OJ 247]--皇帝的新衣(组合数+Lucas定理)
    [Swust OJ 1084]--Mzx0821月赛系列之情书(双线程dp)
    [Swust OJ 404]--最小代价树(动态规划)
    [Swust OJ 610]--吉祥数
    [Swust OJ 137]--波浪数(hash+波浪数构造)
    [Swust OJ 566]--开N方数(牛顿切线法解高次方程)
    [Swust OJ 1125]--又见GCD(数论,素数表存贮因子)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7483418.html
Copyright © 2011-2022 走看看