贪心算法: 绝对值不等式-货仓选址

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;
}
posted @ 2022-07-19 19:10  lucky_light  阅读(129)  评论(0编辑  收藏  举报