贪心-acwing-104-货仓选址
题目:
在一条数轴上有 N 家商店,它们的坐标分别为 A1~AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式
第一行输入整数N。
第二行N个整数A1~AN。
输出格式
输出一个整数,表示距离之和的最小值。
数据范围
1≤N≤100000
输入样例:
4
6 2 9 1
输出样例:
12
题解:
设 仓 库 选 址 为 x , 即 求 m i n ( ∑ i = 1 n ∣ A i − x ∣ ) 。 设仓库选址为x,即求min(\sum_{i=1}^{n}|A_i-x|)。 设仓库选址为x,即求min(∑i=1n∣Ai−x∣)。
我 们 知 道 对 于 任 意 三 点 a , b , c , ∣ a − c ∣ + ∣ b − c ∣ 最 小 值 为 ∣ a − b ∣ , 当 且 仅 当 点 c 在 点 a , b 之 间 时 取 到 。 我们知道对于任意三点a,b,c,|a-c|+|b-c|最小值为|a-b|,当且仅当点c在点a,b之间时取到。 我们知道对于任意三点a,b,c,∣a−c∣+∣b−c∣最小值为∣a−b∣,当且仅当点c在点a,b之间时取到。
那 么 我 们 将 ∑ i = 1 n ∣ A i − x ∣ = ∣ A 1 − x ∣ + ∣ A 2 − x ∣ + . . . + ∣ A n − 1 − x ∣ + ∣ A n − x ∣ 进 行 分 组 配 对 那么我们将\sum_{i=1}^{n}|A_i-x|=|A_1-x|+|A_2-x|+...+|A_{n-1}-x|+|A_n-x|进行分组配对 那么我们将∑i=1n∣Ai−x∣=∣A1−x∣+∣A2−x∣+...+∣An−1−x∣+∣An−x∣进行分组配对
∑ i = 1 n ∣ A i − x ∣ = ( ∣ A 1 − x ∣ + ∣ A n − x ∣ ) + ( ∣ A 2 − x ∣ + ∣ A n − 1 − x ∣ ) + . . . \sum_{i=1}^{n}|A_i-x|=(|A_1-x|+|A_n-x|)+(|A_2-x|+|A_{n-1}-x|)+... ∑i=1n∣Ai−x∣=(∣A1−x∣+∣An−x∣)+(∣A2−x∣+∣An−1−x∣)+...
上 式 子 取 到 最 小 值 当 且 仅 当 x 在 A 1 和 A n 之 间 , 在 A 2 和 A n − 1 之 间 . . . 上式子取到最小值当且仅当x在A_1和A_n之间,在A_2和A_{n-1}之间... 上式子取到最小值当且仅当x在A1和An之间,在A2和An−1之间...
因 此 我 们 先 将 数 组 A 进 行 排 序 , 接 着 取 最 中 间 的 点 即 可 。 因此我们先将数组A进行排序,接着取最中间的点即可。 因此我们先将数组A进行排序,接着取最中间的点即可。
当
n
为
奇
数
时
,
最
后
将
多
出
一
项
最
中
间
的
点
∣
A
n
+
1
2
−
x
∣
未
配
对
,
将
x
设
置
在
点
A
n
+
1
2
上
是
最
优
解
。
当n为奇数时,最后将多出一项最中间的点|A_{\frac{n+1}{2}}-x|未配对,将x设置在点A_{\frac{n+1}{2}}上是最优解。
当n为奇数时,最后将多出一项最中间的点∣A2n+1−x∣未配对,将x设置在点A2n+1上是最优解。
当 n 为 偶 数 时 , 最 中 间 的 分 组 是 ∣ A n 2 − x ∣ + ∣ A n 2 + 1 − x ∣ , 将 x 设 置 在 这 两 点 之 间 ( 包 括 两 点 ) 即 可 。 当n为偶数时,最中间的分组是|A_{\frac{n}{2}}-x|+|A_{\frac{n}{2}+1}-x|,将x设置在这两点之间(包括两点)即可。 当n为偶数时,最中间的分组是∣A2n−x∣+∣A2n+1−x∣,将x设置在这两点之间(包括两点)即可。
综 上 , 最 短 距 离 就 是 将 所 有 商 店 坐 标 排 序 后 , 两 两 配 对 的 距 离 之 和 ∑ i = 1 n 2 ∣ A n − i + 1 − A i ∣ , 最 小 值 在 仓 库 设 置 在 A n + 1 2 的 点 上 取 到 。 综上,最短距离就是将所有商店坐标排序后,两两配对的距离之和\sum_{i=1}^{\frac{n}{2}}|A_{n-i+1}-A_i|,\\最小值在仓库设置在A_{\frac{n+1}{2}}的点上取到。 综上,最短距离就是将所有商店坐标排序后,两两配对的距离之和∑i=12n∣An−i+1−Ai∣,最小值在仓库设置在A2n+1的点上取到。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 0x7fffffff
using namespace std;
const int N=1e5+10;
int n;
int A[N];
ll ans;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&A[i]);
sort(A+1,A+n+1);
for(int i=1;i<=n/2;i++)
ans+=(A[n-i+1]-A[i]);
printf("%lld\n",ans);
return 0;
}