题目大意:有n个精灵位于一维坐标轴上, 每个精灵有一个权值w, 每个精灵走到另一个位置耗费能量S^3 * w。(s是两点间距离)。现在精灵要聚会, 求选取一点,使所有精灵到这点浪费能量之和最小。
分析:设这点的位置是x,精灵位置是pi,则浪费能量值和f = sigma[(pi-x)^3*wi].其中x是变量.
通过对这个函数求二次导可以发现,这个函数是一个下凸函数.可以用
三分做.
具体的三分方法如图:
凸函数:

凹函数:

三分求凸函数极值模板:
//如果一个解函数的二次导恒>0(or <0),则该函数为凸函数.
//精度模板
const double eps = 1e-6;
bool dy(double x,double y) { return x > y + eps;} // x > y
bool xy(double x,double y) { return x < y - eps;} // x < y
bool dyd(double x,double y) { return x > y - eps;} // x >= y
bool xyd(double x,double y) { return x < y + eps;} // x <= y
bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y
double cal(double pos){
/* 根据题目的意思计算 */
}
double solve(double left, double right){
while(xy(left, right)){
double mid = DMID(left, right);
double midmid = DMID(mid, right);
double mid_area = cal(mid);
double midmid_area = cal(midmid);
if (xyd(mid_area, midmid_area)) //下凸函数,上凸函数用dyd(mid_area, midmid_area)
right = midmid;
else
left = mid;
}
return left;
}
HDU 4355 代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include