0
点赞
收藏
分享

微信扫一扫

UVA - 11300 Spreading the Wealth (公式)

西曲风 2023-04-07 阅读 41


题目大意:n个人围城一个圈,每个人手上都有金币,每个人能将他的金币给和他相邻的人,现在要求每人所拥有的金币数要相等,问每个人给出的金币的和的最小值。
解题思路:,最后每个人拥有的金币数为A。
假设第i个人有Ni个金币,给出的金币数为xi,每个人只给其左边的人金币,则其最后的金币数为A = Ni + x(i+1) - xi,变化一下公式得,x(i+1)= A - Ni + xi,设yi = Ni - A,则x(i+1) = xi - yi
n个人的公式为
x2 = x1 - y1, x3 = x2 - y2 …依次类推,xn = x(n-1) - yn
依次代入得,x3 = x1 - (y1+y2), x4 = x1 - (y1+y2+y3)…
设C1 = y1, C2 = y1 + y2…. Cn = y1 + y2 + … + yn
则x2 = x1 - C1, x3 = x1 - C2 …. xn = x1 - C(n-1),又因为所给出的金币肯定为正,所以x2 = |x1-C1|, x3 = |x1-C2|
因为x1 + x2 + x3 + … + xn是最后的答案,要使答案最小,则就要使上面的x1, x2 , x3 ,x4最小,即x1 是C1, C2, C3 … Cn的中位数,所以这题就变成了求中位数问题“

include

include

include

using namespace std;

define maxn 1000010

long long A[maxn], tmp[maxn];

int main() {
int n;
while(scanf(“%d”,&n) == 1) {

long long sum = 0;
    for(int i = 0; i < n; i++) {
        scanf("%lld",&A[i]);    
        sum += A[i];
    }
    long long average = sum / n;

    tmp[0] = 0;
    for(int i = 1; i < n; i++)
        tmp[i] = tmp[i-1] + A[i] - average;

    sort(tmp,tmp+n);
    long long t = tmp[n/2];
    long long ans = 0;

    for(int i = 0; i < n; i++)
        ans += fabs(t - tmp[i]);
    printf("%lld\n",ans);
}
return 0;
}

举报

相关推荐

0 条评论