博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Uva11300/BZOJ1045/BZOJ1465/BZOJ3292
阅读量:5309 次
发布时间:2019-06-14

本文共 1094 字,大约阅读时间需要 3 分钟。

非常玄妙的一道题

一眼贪心?它可能和均分纸牌很像

我们考虑贪心,发现一脸不可做

设每个人手中的糖果数为 Si ,平均值为 ave

假设每个人都给比自己标号小的人分糖果(第 1 个人给第 n 个人),记为 Xi

则有 Si - X+ Xi-1 = ave

列好一个方程组,发现前 n - 1 个方程是可以表出第 n 个方程的,故舍去第 n 个式子

固定 X1, 发现 Xi = (i - 1) * ave - ∑i-1j=1Sj + Xi

将其中的常数设为 -Ci

则有 Ci = ∑i-1j=1Sj - (i - 1) * ave

观察整个方程组发现答案变为 ∑ni=1|X1 - Ci|

看上去还是一脸不可做?

我们发现它的几何意义这时凸显了出来:在坐标轴上有 n 个点 C1, C2, C3, ... , Cn,求使得 X1 到各点的距离和最小的 X的值

那么这个问题突然就变得一脸可做了起来

n 为偶数时,X1 ∈ [Cn/2, C(n/2)+1]

n 为奇数时,X1 = Cn/2

#include
#include
#include
#include
#include
#include
#include
using namespace std; const int MAXN = 1000001; typedef long long ll; int n;ll num[MAXN], c[MAXN]; int main() { scanf("%d", &n); ll ave = 0; for(int i = 1; i <= n; ++i) scanf("%lld", &num[i]), ave += num[i]; ave /= n; for(int i = 1; i <= n; ++i) c[i] = c[i - 1] + num[i] - ave; sort(c, c + n); ll pos = c[(n / 2)]; ll ans = 0; for(int i = 0; i < n; ++i) ans += abs(pos - c[i]); printf("%lld\n", ans); return 0;}

 

转载于:https://www.cnblogs.com/xcysblog/p/9314664.html

你可能感兴趣的文章