• hdu 4923 单调栈


    http://acm.hdu.edu.cn/showproblem.php?pid=4923

    给定一个序列a,元素由0,1组成,求一个序列b,元素在0~1之间,并且保证递增。输出最小的∑(ai−bi)2

    对于每个由连续1开头,连续0结尾的段落有最优值x=a/a+b = sum/len (a为1的个数,b为0的个数),用栈维护各个段的x(d[i])值,如果当前x值小于前面一个段的x值,那么就要将两个段合并,相应调整sum和len.

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define clr0(x) memset(x,0,sizeof(x))
    
    typedef long long LL;
    int a[100005],s[100005],l[100005],r[100005],top;
    double d[100005];
    int main(){
        int n,_;
        RD(_);
        while(_--){
            top = 0;s[0] = 0;
            RD(n);
            for(int i = 1;i <= n;++i){
                RD(a[i]);s[i] = s[i-1]+a[i];
            }
            for(int i = 1;i <= n;){
                int j = i;
                d[++top] = a[i];
                while (j < n && a[j] >= a[j+1])
                    d[top] += a[++j];
                l[top] = i;
                r[top] = j;
                d[top] /= (j-i+1);
                while (top > 1 && d[top] < d[top-1]){
                    r[top - 1] = r[top];
                    --top;
                    d[top] = 1.0*(s[r[top]] - s[l[top]-1]) / (r[top]-l[top]+1);
                }
                i = j+1;
            }
            double ans = 0;
            for (int k=1;k<=top;++k)
                for (int i=l[k];i<=r[k];++i) ans += (d[k]-a[i])*(d[k]-a[i]);
            printf("%.6f
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    dotnet 使用 MessagePack 序列化对象
    dotnet 使用 MessagePack 序列化对象
    PHP die() 函数
    PHP defined() 函数
    PHP define() 函数
    PHP constant() 函数
    PHP connection_status() 函数
    查看物理CPU个数、核数、逻辑CPU个数
    CF997C Sky Full of Stars
    dotnet 使用 lz4net 压缩 Stream 或文件
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4046770.html
Copyright © 2020-2023  润新知