1. 程式人生 > >I - Party All the Time (HDU - 4355)

I - Party All the Time (HDU - 4355)

while urn 所有 因此 ace gpo bsp name clu

- 題目大意

有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\n", j, uh(sum1));

	}
	return 0;
}

  

I - Party All the Time (HDU - 4355)