uva11300分金币

8 篇文章 0 订阅

这个题吧,还是有点难的,那个就是个递推
题意:
n个人围成一圈,每个人都有一些硬币,,每个人只能给左右相邻的人硬币,问最少交换几个硬币,使每个人硬币一样多;

思路:

首先要求出平均数M,每个人的硬币为numi;那么对于1,他能给予4号x1个硬币,并从2号出得到x2个硬币,那么对于1可得numi - x1 + x2 = M;
同理可得numn-xn+x1 = M
就能得到:
x2 =x1-C1 (C1 = num1 - M)
x3 = M - num2 + x2 = 2M-A1-A2+x1 = x1-x2

最后所求为
|x1| + |x1-C1|+…+|x1-Cn-1|,要求这个最小,那么就是要x1为这些数的中位数;

求出x1,在计算和就行了;

这个吧,是别人写的,我一开始没看懂。
后来重点来了就是把那个c2 = c1 + m - a1 .以前认为,c1,c2没联系,其实,c2 = c1 + 什么什么。。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MaxN = 1e6 + 5;
typedef long long LL;

LL a[MaxN] , c[MaxN];
int main()
{
    int n;
    while(~scanf("%d",&n)){
        LL sum = 0 , num = 0;
        for(int i = 1 ; i <= n ; i++)
            scanf("%lld",&a[i]) , sum += a[i];
        int m = (sum / n);
        c[0] = 0;
     //   printf("m = %d\n",m);
        for(int i = 1; i < n ; i++){
            c[i] = c[i - 1] + a[i] - m;
        }
        sort(c , c + n);
     //   for(int i = 1 ; i < n ; i++)
     //       printf("c[%d] = %d\n",i , c[i]);
        int flag = c[n / 2];
      //  printf("flag = %d\n",flag);
        for(int i = 0 ; i < n ; i++){
            num += abs(flag - c[i]);
        }
        printf("%lld\n",num);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值