0
点赞
收藏
分享

微信扫一扫

微软面试题:糖果传递(贪心+线性代数)

yeamy 2022-07-04 阅读 57


文章目录

  • ​​Question​​
  • ​​Ideas​​
  • ​​Code​​

Question

有 n 个小朋友坐成一圈,每人有 a[i] 个糖果。

每人只能给左右两人传递糖果。

每人每次传递一个糖果代价为 1。

求使所有人获得均等糖果的最小代价。

输入格式
第一行输入一个正整数 n,表示小朋友的个数。

接下来 n 行,每行一个整数 a[i],表示第 i 个小朋友初始得到的糖果的颗数。

输出格式
输出一个整数,表示最小代价。

数据范围
1≤n≤1000000,
0≤a[i]≤2×109,
数据保证一定有解。

输入样例:
4
1
2
5
4
输出样例:
4

Ideas

先求平均值,xi >0 代表 ai 给 ai-1 xi 个糖果 xi < 0 代表ai-1 给 ai xi 个糖果。(xi即为代价)
目标就是让所有的xi绝对值求和最小
给完糖果后 ai -xi+xi-1 = ave(平均值)
求解这个方程
可以用x1表示出所有的xi
最后得到一个|x-c| + |x-c|+ … |x-c| 形式的式子
让其最小,就是求x到各个c之间的距离最小
c排序后,x取中位数的时候目标式最小。

Code

# 贪心+线性代数 O(NlogN)
n = int(input())
a = [0 for i in range(n)]
for i in range(n):
a[i] = int(input())

# 求平均值
ave = sum(a) // n

# 求c
c = [0 for i in range(n)]
c[n-1] = ave - a[n-1] # Cn
for i in range(n-2,-1,-1):
c[i] = c[i+1] - ave + a[i+1] # 公式

# 在所有的c中找个x使得所有c到x的距离最小 ==> 排序 + 中位数
c.sort()
res = 0
mid = c[n//2] # 中位数
for i in c:
res += abs(i-mid)
print(res)


举报

相关推荐

0 条评论