最小距离和
題目:在一個平面坐標系中給定()個點,坐標為范圍的絕對值均在范圍內,在軸上找一點
???? 使得這點到所有點的距離之和最短。
?
分析:本題方法是三分,我們知道三分滿足的條件是這個對象必須是單峰函數。題目要求找到最小值,那么也就是說
? ? ?這個距離之和是一個下凸函數,現在來開始證明。
?
? ? ?設要找的點的坐標為,那么設距離之和的函數為,那么得到
? ? ?
?
? ? ?繼續設,對求二階導得到
?
? ? ?
? ? ??
? ? ?在高數中我們學過下面的定理:
? ? ?定理:設在區間上有二階導數,如果,則為上的下凸函數,否則如果,
??????????則為上的上凸函數。
?
???? 那么得到
?
????
?
?????也就是說為凸函數,也就是單峰函數,那么對于凸函數求最值我們利用三分即可。
代碼:
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h>using namespace std; const int N = 100005; const double eps = 1e-8;struct Point {double x,y; };Point p[N];double dist(Point A,Point B) {return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)); }double sum(Point p[],int n,double x) {Point t;t.x = x;t.y = 0;double ans = 0;for(int i=0;i<n;i++)ans += dist(p[i],t);return ans; }double Search(Point p[],int n) {double l = -1e6;double r = 1e6;while(r - l > eps){double ll = (2 * l + r) / 3;double rr = (l + 2 * r) / 3;double ans1 = sum(p,n,ll);double ans2 = sum(p,n,rr);if(ans1 > ans2) l = ll;else r = rr;}return l; }int main() {int T;scanf("%d",&T);while(T--){int n;scanf("%d",&n);for(int i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);printf("%.6lf\n",Search(p,n));}return 0; }?
?
總結
- 上一篇: 又见莫比乌斯反演
- 下一篇: 椭圆中心到椭圆切线的距离