1 条题解
-
0
题意简述
环形均分纸牌。
思路分析
朴素均分纸牌
每个位置初始有纸牌 ,记 ,则分完之后每个位置有 ,每个位置需要分出的纸牌数量记为 。
注意 可能为负数,有两种含义
-
:表示需要将 张牌从 传到 。
-
:表示需要将 张牌从 传到 。
思考分纸牌的过程:
先将 张牌传给 这个位置,此时 。
后将 张牌传给 这个位置,此时 。
然后将 张牌传给 这个位置,此时
当前 个位置的纸牌数均为 ,则第 个位置无需再将纸牌“传给”其他位置,也可以说,。
整个过程中,传递所产生的总代价即为 。
我们发现, 总会叠加在 中,不妨记 。则总代价即可记为 。
环形的均分纸牌
在这种情况下,最优方案一定也是“传递” 次。
我们枚举从位置 开始不断向后“传导”的最优方案。
将 张牌传给 这个位置,此时
将第 张牌传给 这个位置,此时
当前 个位置的纸牌数均为 ,则第 个位置无需再将纸牌传给其他位置,也可以说,。
我们仍然记 ,则从 传导给 的代价是 。
当 时,代价是 。
当 时,代价是 。
我们上文提到过 ,所以化简后,传递的总代价为 。
问题在于如何找到一个 ,使得代价和最小。我们把所有 画在数轴上,发现这个点取得越靠中间,它到其他点的总距离越小,代价和也就越小。所以我们取中位数就可以。
Code
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=1e5+10; int a[N],s[N],sum,n; long long ans; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",a+i),sum+=a[i]; for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i]-sum/n; sort(s+1,s+1+n); for(int i=1;i<=n;i++)ans=(long long)ans+abs(s[i]-s[n/2+1]); printf("%lld\n",ans); return 0; }如有错误,请指出。
-
- 1
信息
- ID
- 4958
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者