HDU 4355 Party All the Time 三分算法

HDU 4355 Party All the Time 三分算法

题意

给你N个人的位置x和相应重量w,他们要到达同一个位置p,他们每个人的花费的精力等于(|s[i]-p|^{3}*w),然后我们需要求一个位置,使得所有人的花费之和最小。

解题思路

根据上面的公式,我们可以知道这个函数不是一个简单的单调函数,最起码是个凹函数(这里需要一个数学上的知识),对于一般情况我们会使用二分法来进行处理,但是这里不是单调函数了,而是一个凹函数,这样我们就不能用二分了,新的算法应运而生——三分算法。

三分算法基本上和二分很相似,就相差了很少的一部分。这里不再讲解,直接推荐相关博客就行了。

三分算法讲解博客推荐
https://blog.csdn.net/huzujun/article/details/81187455

代码实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const int MAXN=5E4+7;
struct nod{
	double x, w;
}node[MAXN];
int t, n; 
double solve(double x)
{
	double sum=0;
	for(int i=0; i<n; i++)
	{
		sum+=pow(abs(x - node[i].x), 3.0) * node[i].w; 
	}
	return sum;
}
int main()
{
	scanf("%d", &t);
	for(int r=1; r<=t; r++)
	{
		scanf("%d", &n);
		double left=1e7, right=-1e6-7;
		for(int i=0; i<n; i++)
		{
			scanf("%lf%lf", &node[i].x, &node[i].w);
			left=min(left, node[i].x);
			right=max(right, node[i].x);
		}
		double ans, mid, midr;
		while(right-left>=esp)
		{
			mid=(left+right)/2;
			midr=(mid+right)/2;
			if(solve(mid) > solve(midr))
				left = mid;
			else right = midr;
		}
		ans=solve(left);
		printf("Case #%d: %d
", r, (int)floor(ans+0.5));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/alking1001/p/12254102.html