题目大意:给你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