• Robert 的军队


    题目描述

    Winter is coming.
    Robert 是个昏庸的君主,整日沉迷于吃喝玩乐,终于,当寒冬降临,他不得不组
    织军队来对抗敌人。
    尽管如此,他仍然是个喜欢玩耍的人,还有点强迫症,他希望选出的军队的所有
    人的身高的方差最小,并且选出的人数 x 要满足 L<=x<=R,因为太少了他怕不够
    气势,太多了他怕会控制不当。
    现在给出 n 个士兵的高度,L 和 R,Robert 找到了聪明的你,希望你帮他解决这
    个难题。

    输入

    第一行三个整数,依次是 n,L,R
    第二行 n 个正整数,表示每个士兵的高度 h

    输出

    一行,表示最小的方差,保留三位小数即可。

    样例输入

    5 3 4
    3 2 4 1 4

    样例输出

    0.222

    样例解释

    这里写图片描述

    数据范围
    对于20%的数据,1<=n<=20
    对于50%的数据,1<=n<=2000,R-L+1<=2000
    对于100%的数据,1<=L<=R<=n<=100000,1<=h[i]<=1000000000

    【题解】

    20%
    1<=n<=20显然直接枚举每个士兵选不选,时间O(n*2^n)

    50%
    我们要做到50分,就首先要得到一个结论:我们先将h从小到大排序,那么我们选择的序列一定是连续的一段。
    这里写图片描述
    由t>0和n>=1,那么后者的方差一定是大于等于前者的,这个存在传递性,所以得证。
    于是就可以枚举开头,枚举长度,然后算一下就好了。

    100%
    对于100分的算法,我们需要另外一个结论:任意一个序列,它加上一个新元素不会使得其方差更优。
    证明与上面类似我就不说了。
    然后就是说我们只用求长度为L的序列中的方差的最大值,于是直接扫一遍计算就好了。

    当然,上面是出题人的题解,有点麻烦,我自己来搞一个。
    拆一波方差公式
    这里写图片描述
    然后这个公式就可以维护前缀和了。
    于是,从1开始枚举长度为L的子序列即可(当然要以前面题解给出的两个结论为基础)。O(1)询问跑的飞快。

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #define ll long long
    #define re register
    #define il inline
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int MAX=100005;
    int n,L,R;
    double h[MAX],sum[MAX],tot[MAX];
    double ans=2147483646.0;
    void calc(int l,int r)
    {
        double res;
        res=(tot[r]-tot[l-1])/(L*1.0)-((sum[r]-sum[l-1])/(L*1.0))*((sum[r]-sum[l-1])/(L*1.0));//就是方差公式拆完的结果
        ans=min(ans,res);
    }
    void solve()
    {
        fp(i,L,n)//从1开始枚举长度为L的子序列
            calc(i-L+1,i);
    }
    il int gi()
    {  
      re int x=0;
      re short int t=1;
      re char ch=getchar();
      while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    int main()
    {
        freopen("army.in","r",stdin);
        freopen("army.out","w",stdout);
        n=gi();L=gi();R=gi();
        fp(i,1,n) h[i]=gi();
        sort(h+1,h+1+n);
        fp(i,1,n) sum[i]=sum[i-1]+h[i],tot[i]=tot[i-1]+h[i]*h[i];//sum存ai的前缀和,tot存ai^2的前缀和
        solve();
        printf("%.3lf
    ",ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    程序员开发网站必知的知识点
    自己动手写Session
    数据显示控件的通用分页代码
    自己动手写验证码
    ASP.NET高级技术个人随笔
    About Exception Handling
    使用CruiseControl搭建自己的持续集成环境
    Exception about "Could not load file or assembly Namespace.Components' or one of its dependencies."
    Do I need the Application Server role for a web server?
    A networkrelated or instancespecific error occurred while establishing a connection to SQL Server
  • 原文地址:https://www.cnblogs.com/yanshannan/p/7413152.html
Copyright © 2020-2023  润新知