【学习笔记】贪心好题!

阅读: 评论:0

【学习笔记】贪心好题!

【学习笔记】贪心好题!

  这是一篇持续更新的博客。

  不废话了直接上题吧。

  1.洛谷 P2512 糖果传递

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

    题解:最终结果可以计算,记为S。

       我们假设所有传递都是向左传递(有向右的自然成为负数),设每个人的传递数量是Ki,这样便于统计。

       那么对于第i个小朋友,他最后的糖果数量就是 Ai-Ki+Ki+1。这个数值等于S。

       可以列出n个方程。

       S=A1-K1+K2 移向得 K2=S-A1+K1。

       S=A2-K2+K3 代换得 K3=S-A2+K2=S-A2+S-A1+K1=2*S-A1-A2+K1。

       依次代换下去,可以得到第n个方程是Kn=n*S-A1-A2-…-An+K1。

       设Ci=Ai-S。

       K2=K1-C1

       K3=K1-C2

       所以我们传递数量的总和就变成了|K1|+|K1-C1|+…+|K1-Cn-1|.

       可以抽象成一个数轴,上面有K1 C1 C2 C3 … Cn-1这n个点。取其中一个点使得所有距离尽可能近。

       答案在中位数取到,于是就可以轻松的AC了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long n,a[1000001],k[1000001],sum,ans;
 4 int main()
 5 {
 6     scanf("%lld",&n);
 7     for(int i=1;i<=n;i++)
 8     {
 9         scanf("%lld",&a[i]);
10         sum+=a[i];
11     }
12     sum/=n;
13     for(int i=1;i<=n;i++)
14     {
15         k[i]=k[i-1]-a[i]+sum;
16     }
17     sort(k+1,k+n+1);
18     int mid=k[(n+1)/2];
19     for(int i=1;i<=n;i++)
20     {
21         ans+=abs(k[i]-mid);
22     }
23     printf("%lld",ans);
24     return 0;
25 }
View Code

转载于:.html

本文发布于:2024-01-28 07:54:05,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063996495923.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:贪心   学习笔记
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23