51Nod - 1098 最小方差
阿新 • • 發佈:2017-05-27
power size out https ref clas 方差 online space
51Nod - 1098 最小方差
若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的整數部分。Input示例
5 3 1 2 3 4 5Output示例
2
題解:
求 x(i+1) + x(i+2) + ... + x(i+2) 的平方差,
(x[i+1] - avg)^2 + (x[i+2] - avg)^2 + ... + (x[i+n] - avg)^2 = (x[i+1] ^ 2 + x[i+2]^2 + .. + x[i+n]^2 - 2*avg*(x[i+1] + ... + x[i+n]) + n*avg*avg )
根據這個可以將時間由O(n*m) 縮小到O(n)
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; const int MAXN = 10000 + 10; int n, m, num[MAXN], pow2[MAXN]; int cmp(const void *a, const void *b){ return (*(int *)a - *(int *)b); } int main(){ long long ans, sum_power, sum_num, tmp; double avg; while(scanf("%d %d", &m, &n) != EOF){ for(int i=0; i<m; ++i){ scanf("%d", &num[i]); } qsort(num, m, sizeof(num[0]), cmp); for(int i=0; i<m; ++i){ pow2[i] = num[i] * num[i]; } sum_num = 0; sum_power = 0; for(int i=0; i<n; ++i){ sum_num += num[i]; sum_power += pow2[i]; } avg = sum_num *1.0 / n; ans = (long long)(sum_power - 2*avg*sum_num + n*avg*avg); for(int i=n; i<m; ++i){ sum_num += num[i] - num[i-n]; sum_power += pow2[i] - pow2[i-n]; avg = sum_num *1.0 / n; tmp = (long long)(sum_power - 2*avg*sum_num + n*avg*avg); if(tmp < ans){ ans = tmp; } } printf("%lld\n", ans ); } return 0; }
51Nod - 1098 最小方差