C++题解:货仓选址

题目描述

在一条数轴上有 N N N 家商店,它们的坐标分别为 A 1 A_1 A1 A N A_N AN

现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。

为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。

输入格式

第一行输入整数 N N N

第二行 N N N 个整数 A 1 A_1 A1 A N A_N AN

输出格式

输出一个整数,表示距离之和的最小值。

数据范围

1 ≤ N ≤ 100000 1≤N≤100000 1N100000,

0 ≤ A i ≤ 40000 0≤A_i≤40000 0Ai40000

输入样例

4
6 2 9 1

输出样例

12

解题思路(绝对值不等式)

f ( x ) f(x) f(x)表示把货仓建在 x x x位置时距离之和的最小值,那么:
f ( x ) = ∣ X 1 − x ∣ + ∣ X 2 − x ∣ + . . . + ∣ X n − x ∣ f(x) = |X_1 - x| + |X_2 - x| + ... + |X_n - x| f(x)=X1x+X2x+...+Xnx
分组,将第一项和最后一项分一组,第二项和倒数第二项一组…,那么
f ( x ) = ( ∣ X 1 − x ∣ + ∣ X n − x ∣ ) + ( ∣ X 2 − x ∣ + ∣ X n − 1 − x ∣ ) + . . . f(x) = (|X_1 - x| + |X_n - x|) + (|X_2 - x| + |X_{n-1} - x|) + ... f(x)=(X1x+Xnx)+(X2x+Xn1x)+...
因为:
∣ X 1 − x ∣ + ∣ X n − x ∣ > = X n − X 1 . . . |X_1 - x| + |X_n - x| >= X_n - X_1 ... X1x+Xnx>=XnX1...
所以:
f ( x ) > = X n − X 1 + X n − 1 − X 2 . . . f(x) >= X_n - X_1 + X_{n-1} - X_2... f(x)>=XnX1+Xn1X2...
如果
f ( x ) = X n − X 1 + X n − 1 − X 2 . . . , f(x) = X_n - X_1 + X_{n-1} - X_2..., f(x)=XnX1+Xn1X2...
f ( x ) f(x) f(x)为最小值。那么 x x x 建在中位数的位置,即 a [ n / 2 ] a[n / 2] a[n/2]时,满足距离之和的最小值。此时 a [ n / 2 ] a[n / 2] a[n/2]为序列的中位数。

中位数(Median)又称中值,指按顺序排列的一组数据中居于中间位置的数。

代码实现

#include 
#include 
#include 
using namespace std;
const int N = 100010;
int a[N];
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    sort(a, a + n);
    int res = 0;
    for(int i = 0; i < n; i++) res += abs(a[i] - a[n / 2]);
    printf("%d\n", res);
    return 0;
}

你可能感兴趣的:(贪心算法)