题目大意:求Y=Σw=Σ(wi*|xi-X|3) 使得Y达到最小的那个Ymin.
这是一个凸函数,因为它的二次导大于0,适用于三分(这个凸函数有两种形式,下次贴图)
由于函数不是单调的,所以二分不可行,要用三分来做,mid=(l+r)/2,mid2=(mid+r)/2,然后f(x)较大的那个点作为新的l/r边界,慢慢缩小范围。
AC代码
#include<bits/stdc++.h>
#define eps 1e-7
using namespace std;
double x[50010],w[50010];
int T,n;
double cal(double c)
{
double sum=0;
for(int i=1;i<=n;i++) sum+=fabs(x[i]-c)*fabs(x[i]-c)*fabs(x[i]-c)*w[i];
return sum;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&w[i]);
double l=-1000000,r=1000000;
while(fabs(l-r)>=eps)
{
double mid1=(l+r)/2,mid2=(mid1+r)/2;
if(cal(mid1)+eps<cal(mid2)) r=mid2;
else l=mid1;
}
printf("%.0lf\n",cal(l));
}
return 0;
}