C++题解:货仓选址

探讨如何通过计算在给定N家商店坐标下,将货仓建在哪个位置能使得到各商店的距离之和达到最小。使用绝对值不等式原理,关键在于货仓应建在中位数位置,以平衡所有商店间的运输成本。通过实例和代码实现展示了这一问题的解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

在一条数轴上有 NNN 家商店,它们的坐标分别为 A1A_1A1ANA_NAN

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

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

输入格式

第一行输入整数 NNN

第二行 NNN 个整数 A1A_1A1ANA_NAN

输出格式

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

数据范围

1≤N≤1000001≤N≤1000001N100000,

0≤Ai≤400000≤A_i≤400000Ai40000

输入样例

4
6 2 9 1

输出样例

12

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

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

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

代码实现

#include <iostream>
#include <algorithm>
#include <cmath>
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少儿编程乔老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值