Uva11300/BZOJ1045/BZOJ1465/BZOJ3292
非常玄妙的一道题
一眼贪心?它可能和均分纸牌很像
我们考虑贪心,发现一脸不可做
设每个人手中的糖果数为 Si ,平均值为 ave
假设每个人都给比自己标号小的人分糖果(第 1 个人给第 n 个人),记为 Xi
则有 Si - Xi + 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 到各点的距离和最小的 X1 的值
那么这个问题突然就变得一脸可做了起来
n 为偶数时,X1 ∈ [Cn/2, C(n/2)+1]
n 为奇数时,X1 = Cn/2
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cctype> #include<cstdio> #include<cmath> 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; }
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/