【中位数 && 题解 && 蓝书刷题】糖果传递

5 篇文章 0 订阅
4 篇文章 0 订阅

题目描述:

有nnn个小朋友坐成一圈,每人有a[i]a[i]a[i]个糖果。每人只能给左右两人传递糖果,传递一个糖果代价为1,求使所有人获得均等糖果的最小代价。


Solution

这道题所要求的是想让每个数都平均,所以我们得求出这堆数的平均数 p j pj pj
这道题对于每一个人而言有两个方向的状态,这个很麻烦
其实我们可以把方向就看见一条,用正负性表示

我们设 s [ i ] s[i] s[i]表示第i个人给了第i+1个人多少个糖果,由于是一个环,所以 s [ n ] s[n] s[n]表示为第n个人给了第一个人多少糖果

根据以上,我们可以得出第i个人一共有 s [ i − 1 ] + a [ i ] s[i-1]+a[i] s[i1]+a[i]颗糖果
但是第i个人只需要保留 p j pj pj颗糖果,所以 s [ i ] = s [ i − 1 ] + a [ i ] − s u m s[i]=s[i-1]+a[i]-sum s[i]=s[i1]+a[i]sum

我们得出了 s s s数组,就知道每个人之间的关系,这个时候我们就只需要找一个人为基准值,使他为基准传出去的糖果的总和最小

根据我们以往的做题经验,这个人便是所有人的中位数。


Code

#include<bits/stdc++.h>
using namespace std;
int n;
int a[1010100];
int s[1010100];
#define int long long
signed main(){
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	int pj = 0;
	scanf("%lld",&n);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]) , pj+=a[i];
	pj/=n;
	for (int i=1;i<=n;i++) s[i] = a[i]+s[i-1]-pj;
	sort(s+1,s+n+1);
	pj = 0;
	for (int i=1;i<=n;i++) pj+=abs(s[n/2+1]-s[i]);
	printf("%lld",pj);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值