
这是一篇持续更新的博客。
不废话了直接上题吧。
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 条评论) |