1. 程式人生 > >51nod_1098_最小方差

51nod_1098_最小方差

algo lac 別人 sin b- i++ nod 變化 -s

若x1,x2,x3......xn的平均數為k。 則方差s^2 = 1/n * [(x1-k)^2+(x2-k)^2+.......+(xn-k)^2] 。 方差即偏離平方的均值,稱為標準差或均方差,方差描述波動程度。

給出M個數,從中找出N個數,使這N個數方差最小。

Input
第1行:2個數M,N,(M > N, M <= 10000)
第2 - M + 1行:M個數的具體值(0 <= Xi <= 10000)
Output
輸出最小方差 * N的整數部分。

鏈接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1098

都是通過遞推的,但我的方法沒化簡到底,所以比別人慢了點;
先放我的代碼
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cstdlib>
#define getrand(a,b) (int)((rand()/33000.0)*((b)-(a)+1))+(a)
using namespace std;
typedef long long LL;
const int maxnn=100+5;
const int maxn=100000+5;
const int mod=1e9+7;
double num[10001];
int main() { int m,n;LL ans; double a=0,b=0,k,derta,x;//a:方差*n,b:n個數的和,k:均值 cin>>m>>n; //derta:均值變化量 for(int i=0;i<m;i++){ cin>>num[i]; } sort(num,num+m); // for(int i=0;i<m;i++) // cout<<num[i]<<‘ ‘; // cout<<endl; int
f,l;//首位標號 f=0;l=0; for(int i=0;i<n;i++)b+=num[i]; k=b/(double)n; // cout<<k<<endl; while(l<n){ x=num[l]-k; a+=x*x; l++; } l--;ans=a; double x1;//臨時變量 m=m-1; while(l<m){ l++; a-=(num[f]-k)*(num[f]-k); // cout<<a<<‘ ‘;//1 b-=num[f++]; // cout<<b<<‘ ‘;//2 x1=k; k=(b+num[l])/(float)n; // cout<<k<<‘ ‘;//3 derta=k-x1; // cout<<derta<<‘ ‘;//4 a=a-derta*(b-(n-1)*x1)*2+(n-1)*derta*derta; // cout<<a<<‘ ‘;//5 b+=num[l]; // cout<<b<<‘ ‘;//6 a+=(num[l]-k)*(num[l]-k); // cout<<a<<‘ ‘<<endl; if(a<ans)ans=a; } cout<<ans<<endl; return 0; }

別人的較好代碼

#include <iostream>
#include<stdio.h>
#include<algorithm>
#define MAX_N 10001
int a[MAX_N];
using namespace std;

int main()
{
    int M,N;
    scanf("%d%d", &M,&N);
    for(int i=0; i<M; i++)
    scanf("%d", a+i);
    sort(a, a+M);
    long long sqrSum = 0;
    long long sum = 0;
    for(int i=0; i<N; i++)
    {
        sqrSum += a[i]*a[i];
        sum += a[i];
    }
    long long ans = sqrSum-sum*sum*1.0/N;
    for(int i=N; i<M; i++)
    {
        sqrSum -= a[i-N]*a[i-N];
        sum -= a[i-N];
        sqrSum += a[i]*a[i];
        sum += a[i];
        ans = min(ans, (long long)(sqrSum-sum*sum*1.0/N));
    }
    printf("%lld\n", ans);
    return 0;
}

51nod_1098_最小方差