题意:一维坐标轴上有一些点,每个点都有独自的点权,求找出一个点使所有的点聚到这点的代价最小,代价计算公式是待选择点坐标与数轴上点坐标的差的三次方乘点权,把所有的点的代价加起来;
思路:因为求和的表达式是一个函数,导之发现有最小值,三分模板
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const double eps=1e-6; const int maxn=1e6+6; double arr[maxn]; double pos[maxn]; int n; double getsum(double x) { double sum=0; for(int i=1;i<=n;i++) { double cnt=fabs(x-pos[i]); cnt=cnt*cnt*cnt; sum+=cnt*arr[i]; } return sum; } double triserch(double l,double r) { while(r-l>eps) { double ml=l+(r-l)/3.0; double mr=r-(r-l)/3.0; if(getsum(ml) < getsum(mr)) { r=mr; } else { l=ml; } } return getsum(l); } int main() { int T; scanf("%d",&T); int Cas=1; while(T--) { double l=1000000; double r=-1000000; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf%lf",&pos[i],&arr[i]); if(pos[i] < l) l=pos[i]; if(pos[i]>r) r=pos[i]; } printf("Case #%d: %.0lf\n",Cas++,triserch(l,r)); } }