- 题目大意
有n个精灵在一维坐标轴上,并且每个精灵都有一个权值,每个精灵从一个点到达一个点要花费:S3*W(s代表距离),问所有的精灵要聚在一起,最小花费是多少。
- 解题思路
设最终要求的点的位置是x,则花费为:∑fabs(x[i]-x)^3*w[i]。又因为次函数为凸函数(求二次导就知道了),因此我们可以用三分法去解决这个问题。(最后注意用double)
- 代码
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstdio>
using namespace std;
const int MAX = 50020;
const double eps = 1e-7;
int n;
double wz[MAX];
double num[MAX];
double uh(double x)
{
double sum = 0;
for (int i = 0; i < n; i++)
{
double c = fabs(wz[i] - x);
sum += c * c*c*num[i];
}
return sum;
}
double find(double l, double r)
{
double la, ra;
while (r - l > eps)
{
la = (l * 2 + r) / 3;
ra = (l + 2 * r) / 3;
if (uh(la) > uh(ra))
l = la;
else
{
r = ra;
}
}
return l;
}
int main()
{
int t;
scanf("%d", &t);
for (int j = 1; j <= t; j++)
{
scanf("%d", &n);
double r = -1e7, l = 1e7;
for (int i = 0; i < n; i++)
{
scanf("%lf%lf", &wz[i], &num[i]);
if (wz[i] < l)
l = wz[i];
if (wz[i] > r)
r = wz[i];
}
double sum1 = find(l, r);
printf("Case #%d: %.0f
", j, uh(sum1));
}
return 0;
}