绝对值不等式

acwing 104.货仓选址

 题意:需要在竖轴上选一个点,使该点到其他给出点的距离之和最小。将其抽象为数学公式$\left | x - c_1 \right |+\left | x-c_2 \right |+\left | x-c_3 \right |+\cdot \cdot \cdot \left | x-c_k \right |$,求该公式的最小值。

可以知道,该公式的最小值就是取$c_1, c_2, c_3,\cdot \cdot \cdot c_k$的中位数。

证明:

当只有一个点的时候,选在该点肯定为最小,当有两个点的时候,选在两个点中间的任何一个位置都为最小,当有三个点的时候,选在中间那个点的位置。我们将每个点两两分组。

①当$k$为奇数时,$x_1$和$x_k$一组,$x_2$和$x_{k -1}$一组,最后剩$x_{\fact_{k + 1}{2}}$单独一组,可以知道,选择每一组中间的点都是最小的。而$x_{\fact_{k + 1}{2}}$这一组要选在这个点上最小,所以选在$x_{\fact_{k + 1}{2}}$上的时候,满足该组的值最小,也满足其他组的值最小,所以总和最小。

②当$k$为偶数时,每一组都是两两配对,选择每组中间的位置就最小值,而最靠近中心的两个点的那个区间,选择任意一个在该区间内的点,都可以做到使得每一组的答案最小。

思路:读入一个$a$数组,排序,找出中位数,用所有数减去中位数的绝对值相加即为答案。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 const int N = 1e5+10;
 8 int a[N];
 9 int n;
10 
11 int main(){
12     cin >> n;
13     for(int i = 0 ; i < n ; i ++)cin >> a[i];
14     
15     sort(a, a + n);
16     int c = a[n / 2];
17     
18     int res = 0;
19     for(int i = 0 ; i < n ; i ++)res += abs(a[i] - c);
20     
21     cout << res << endl;
22     return 0;
23 }

猜你喜欢

转载自www.cnblogs.com/1-0001/p/12605095.html