首页 > 其他 > 详细

最小距离和

时间:2014-04-20 17:28:44      阅读:673      评论:0      收藏:0      [点我收藏+]

题目:在一个平面坐标系中给定bubuko.com,布布扣bubuko.com,布布扣个点,坐标为范围的绝对值均在bubuko.com,布布扣范围内,在bubuko.com,布布扣轴上找一

     使得这点到所有点的距离之和最短。

 

分析:本题方法是三分,我们知道三分满足的条件是这个对象必须是单峰函数。题目要求找到最小值,那么也就是说

     这个距离之和是一个下凸函数,现在来开始证明。

 

     设要找的点的坐标为bubuko.com,布布扣,那么设距离之和的函数为bubuko.com,布布扣,那么得到


     bubuko.com,布布扣

 

     继续设bubuko.com,布布扣,对bubuko.com,布布扣求二阶导得到

 

     bubuko.com,布布扣

      

     在高数中我们学过下面的定理:


     定理:bubuko.com,布布扣在区间bubuko.com,布布扣上有二阶导数,如果bubuko.com,布布扣,则bubuko.com,布布扣bubuko.com,布布扣上的下凸函数,否则如果bubuko.com,布布扣

          则bubuko.com,布布扣bubuko.com,布布扣上的上凸函数。

 

     那么得到

 

     bubuko.com,布布扣

 

     也就是说bubuko.com,布布扣为凸函数,也就是单峰函数,那么对于凸函数求最值我们利用三分即可。


代码:

#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;
}

 

 


最小距离和,布布扣,bubuko.com

最小距离和

原文:http://blog.csdn.net/acdreamers/article/details/24125911

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!