题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4355
题意:
小精灵不愿意走路,走路的话会使他们产生不高兴值,如果小精灵走的路是S体重是W那么他走S路程产生的不高兴值是ans=sigma(S^3)*W;现在森林里要开一个庆祝会,给出各个小精灵的坐标(注意这里是一维的)和体重,求在哪里庆祝会使小精灵的不高兴值最小,输出这个最小的不高兴值。样例中第一行是样例个数,每个样例的第一行是小精灵的个数n,接下的n行是每个小精灵的坐标和体重。输出只有一个整数,即最小的不高兴值。注意输出格式。
分析:
F(x) = sigma |xi – x|^3*w;
求导后发现是一个凸性函数,然后三分
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn=50000+5;
double p[maxn],w[maxn];
const double eps=1e-6;
int n;
double cal(double x)
{
double ans=0;
for(int i=0; i<n; i++)
{
double s=fabs(p[i]-x);
ans+=s*s*s*w[i];
}
return ans;
}
double get(double l, double r)
{
double ll,rr;
while(r-l>eps)
{
double ll=(l*2+r)/3;
double rr=(l+2*r)/3;
if(cal(ll)>cal(rr))
l=ll;
else
r=rr;
}
return l;
}
int main()
{
int t,cnt=1;
cin>>t;
for(int cas=1; cas<=t; cas++)
{
scanf("%d",&n);
double r=-99999999,l=99999999;
for(int i=0; i<n; i++)
{
scanf("%lf%lf",&p[i],&w[i]);
if(p[i]<l)
l=p[i];
if(p[i]>l)
r=p[i];
}
double ss=get(l,r);
printf("Case #%d: %.0lf\n",cas,cal(ss));
}
return 0;
}