贪心算法: 绝对值不等式-货仓选址
c++
AcWing 104. 货仓选址
/*
Acwing 104. 货仓选址
问题描述:
在一条数轴上有 N 家商店,它们的坐标分别为 A1∼AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式:
第一行输入整数 N。
第二行 N 个整数 A1∼AN。
输出格式:
输出一个整数,表示距离之和的最小值。
数据范围:
1 ≤ N ≤ 100000,
0 ≤ Ai ≤ 40000
求解思路:
如果单论如何寻找最小值,求解是有些麻烦的,但是我们观察点 x, y (x <= y)可以发现,商店 p 位于 [x, y] 区间中的任意一点都可以使得 dist[x] + dist[y] 最小。
因此,倘若我们对 数组 a 排序, i = 1, j = n 最后头指针和尾指针 进行配对移动, i ++, j --,可以不断使得 dist[i] + dist[j] 最小,并且因为我们对 a 数组进行排序,
保证了多个数对之前 最小 dist 取得条件是不会冲突的。 最终找到最优解。
这个点使得他对所有的点都是最优的,因此他全局也是最优的。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int a[N], n;
LL solution() {
// sort
sort(a + 1, a + n + 1);
LL res = 0;
for (int i = 1, j = n; i <= j; i ++, j -- ) {
if (i == j) {
break;
} else {
res += a[j] - a[i];
}
}
return res;
}
int main()
{
// input
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) {
scanf("%d", &a[i]);
}
// solve and output
LL res = solution();
printf("%lld\n", res);
return 0;
}