【Leetcode】1515. Best Position for a Service Centre

题目地址:

https://leetcode.com/problems/best-position-for-a-service-centre/description/

给定 n n n个平面坐标系的坐标 ( x 0 , y 0 ) , . . . , ( x n − 1 , y n − 1 ) (x_0,y_0),...,(x_{n-1},y_{n-1}) (x0,y0),...,(xn1,yn1),求: min ⁡ ( x , y ) ∑ i ( x i − x ) 2 + ( y i − y ) 2 \min_{(x,y)} \sum_i\sqrt{(x_i-x)^2+(y_i-y)^2} (x,y)mini(xix)2+(yiy)2

f ( x , y ) = ∑ i ( x i − x ) 2 + ( y i − y ) 2 f(x,y)=\sum_i\sqrt{(x_i-x)^2+(y_i-y)^2} f(x,y)=i(xix)2+(yiy)2 ,其海森矩阵为 H ( f ) = [ ∂ 2 f ∂ x 2 ∂ 2 f ∂ x ∂ y ∂ 2 f ∂ y ∂ x ∂ 2 f ∂ y 2 ] = [ ∑ i ( y i − y ) 2 [ ( x i − x ) 2 + ( y i − y ) 2 ] 3 / 2 ∑ i ( x i − x ) ( y i − y ) [ ( x i − x ) 2 + ( y i − y ) 2 ] 3 / 2 ∑ i ( x i − x ) ( y i − y ) [ ( x i − x ) 2 + ( y i − y ) 2 ] 3 / 2 ∑ i ( x i − x ) 2 [ ( x i − x ) 2 + ( y i − y ) 2 ] 3 / 2 ] H(f) = \begin{bmatrix} \frac{\partial^2 f}{\partial x^2} & \frac{\partial^2 f}{\partial x \partial y} \\ \frac{\partial^2 f}{\partial y \partial x} & \frac{\partial^2 f}{\partial y^2} \end{bmatrix}=\begin{bmatrix} \sum_{i} \frac{(y_i - y)^2}{\left[(x_i - x)^2 + (y_i - y)^2\right]^{3/2}} & \sum_{i} \frac{(x_i - x)(y_i - y)}{\left[(x_i - x)^2 + (y_i - y)^2\right]^{3/2}} \\ \sum_{i} \frac{(x_i - x)(y_i - y)}{\left[(x_i - x)^2 + (y_i - y)^2\right]^{3/2}} & \sum_{i} \frac{(x_i - x)^2}{\left[(x_i - x)^2 + (y_i - y)^2\right]^{3/2}} \end{bmatrix} H(f)=[x22fyx2fxy2fy22f]= i[(xix)2+(yiy)2]3/2(yiy)2i[(xix)2+(yiy)2]3/2(xix)(yiy)i[(xix)2+(yiy)2]3/2(xix)(yiy)i[(xix)2+(yiy)2]3/2(xix)2 是半正定的,从而 f f f是凸函数,从而 g ( x ) = inf ⁡ y f ( x , y ) g(x)=\inf_y f(x,y) g(x)=infyf(x,y)对于 x x x来讲也是凸函数。单元凸函数求最小值可以用三分法,而二维凸函数求最小值可以用三分套三分的方法。代码如下:

class Solution {
 public:
  double getMinDistSum(vector<vector<int>>& ps) {
    constexpr double eps = 1e-8;
    double l = 0, r = 100.0;
    auto get_sum = [&](double x, double y) {
      double sum = 0.0;
      for (auto& p : ps) {
        double a = p[0], b = p[1];
        sum += sqrt((x - a) * (x - a) + (y - b) * (y - b));
      }
      return sum;
    };
    auto calc = [&](double x) -> double {
      double l = 0, r = 100;
      while (r - l > eps) {
        double y1 = l + (r - l) / 3, y2 = l + (r - l) / 3 * 2;
        if (get_sum(x, y1) >= get_sum(x, y2))
          l = y1;
        else
          r = y2;
      }
      return get_sum(x, l);
    };
    while (r - l > eps) {
      double x1 = l + (r - l) / 3, x2 = l + (r - l) / 3 * 2;
      if (calc(x1) > calc(x2))
        l = x1;
      else
        r = x2;
    }
    return calc(l);
  }
};

时间复杂度 O ( log ⁡ r / ϵ ) O(\log r/\epsilon) O(logr/ϵ) r r r是数据范围,空间 O ( 1 ) O(1) O(1)

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值