第六章贪心(三):排序不等式、绝对值不等式、推公式
AcWing 913:排队打水
题目
有 n 个人排队到 1 个水龙头处打水,第 i 个人装满水桶所需的时间是 ti,请问如何安排他们的打水顺序才能使所有人的等待时间之和最小?
输入格式
第一行包含整数 n。
第二行包含 n 个整数,其中第 i 个整数表示第 i 个人装满水桶所花费的时间 ti。
输出格式
输出一个整数,表示最小的等待时间之和。
解答
t1, t2, t3, … , tn
总时间 = t1×(n-1) + t2×(n-2) + t3×(n-3) + …
按照从小到大的顺序排队,总时间最小。
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int main()
{
int n;
int time[N];
scanf("%d", &n);
for(int i=0;i<n;i++) scanf("%d", &time[i]);
sort(time, time + n);
reverse(time, time + n);
LL result = 0;
for(int i=0;i<n;i++) result += time[i]*i;
printf("%lld\n", result);
return 0;
}
AcWing 104 货仓选址
题目
在一条数轴上有 N 家商店,它们的坐标分别为 A1∼AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式
第一行输入整数 N。
第二行 N 个整数 A1∼AN。
输出格式
输出一个整数,表示距离之和的最小值。
解答
由三角不等式(绝对值不等式)可知,将货仓建在中位数的位置时距离之和最小。首先进行排序。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int main()
{
int n;
int warehouse[N];
scanf("%d", &n);
for(int i=0; i<n; i++) scanf("%d", &warehouse[i]);
sort(warehouse, warehouse + n);
int result = 0;
for(int i=0; i<n; i++) result += abs(warehouse[i] - warehouse[n/2]);
printf("%d\n", result);
return 0;
}