标签:
题目大意:给你n个点,拿走k个之后,让你求出怎么拿使得剩下的inertia最小。
解体思路:贪心的策略。剩下的数只有当连续的时候,值会最小,枚举一遍求出来间距为n-k的最小的inertia。
PS:(x1-d)^2+(x2-d)^2+……+(xn-d)^2 = sum(x1^2+……+xn^2)+n*d*d-2*n(sum(x1+x2+……+xn)).
2 3 2 -1 0 1 4 2 -2 -1 1 2
0 0.5
#include <algorithm> #include <iostream> #include <stdlib.h> #include <string.h> #include <iomanip> #include <stdio.h> #include <string> #include <queue> #include <cmath> #include <stack> #include <ctime> #include <map> #include <set> #define eps 1e-9 ///#define M 1000100 ///#define LL __int64 #define LL long long ///#define INF 0x7ffffff #define INF 0x3f3f3f3f #define PI 3.1415926535898 #define zero(x) ((fabs(x)<eps)?0:x) #define mod 1000000007 using namespace std; const int maxn = 50110; double sum1[maxn], sum2[maxn]; double num[maxn]; int main() { int T; cin >>T; while(T--) { int n, k; cin >>n>>k; for(int i = 1; i <= n; i++) scanf("%lf",&num[i]); sort(num+1, num+1+n); memset(sum1, 0, sizeof(sum1)); memset(sum2, 0, sizeof(sum2)); int m = n-k; if(!m) { printf("0.0000000000\n"); continue; } double Min = 1000000000000000000.0; for(int i = 1; i <= n; i++) { sum1[i] = sum1[i-1]+num[i]; sum2[i] = sum2[i-1]+num[i]*num[i]; } for(int i = 1; i <= n-m+1; i++) { int x = i; int y = i+m-1; double d = (sum1[y]-sum1[x-1])/m*1.0; double tmp = (sum2[y]-sum2[x-1]) + m*1.0*d*d-2.0*d*(sum1[y]-sum1[x-1]); Min = min(Min, tmp); } printf("%.10lf\n",Min); } }
标签:
原文地址:http://blog.csdn.net/xu12110501127/article/details/42781825