題意:一維座標軸上有一些點,每個點都有獨自的點權,求找出一個點使所有的點聚到這點的代價最小,代價計算公式是待選擇點座標與數軸上點座標的差的三次方乘點權,把所有的點的代價加起來;
思路:因爲求和的表達式是一個函數,導之發現有最小值,三分模板
#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));
}
}