n 人の子供が輪になって座っており、それぞれ a[i] 個のキャンディーを持っています。
一人一人が左右にしかキャンディーを渡すことができません。
キャンディーを渡すたびに、1 人につき 1 のコストがかかります。
誰もが平等にキャンディーを提供できる最低価格を見つけます。
入力フォーマット
最初の行に、子の数を示す正の整数 n を入力します。
次の n 行では、各行に整数 a[i] が含まれており、i 番目の子が最初に取得するキャンディーの数を示しています。
出力フォーマット
最小コストを表す整数を出力します。
データ範囲
1≤n≤1000000、0≤a
[i]≤2×109、
データには解があることが保証されています。
入力サンプル:
4
1
2
5
4
出力例:
4
#include <iostream>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int n,a[1000001],c[1000001],ave;ll sum;
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i ++)
{
scanf("%d",&a[i]);
sum += a[i];
}
ave = sum / n;
for(int i = 2; i <= n; i ++)
c[i] = c[i - 1] + a[i] - ave;
sort(c + 1 , c + n + 1);
ll ans = 0;
int mid = c[(n >> 1) + 1];
for(int i = 1; i <= n; i ++)
ans += abs(c[i] - mid);
printf("%lld",ans);
return 0;
}
まず、各子供のキャンディーの最終的な数を計算できます。これは、平均で表されるキャンディーの総数を n で割った値に等しくなります。
i というラベルの付いた子供が Ai キャンディーを持ち始めたとすると、Xi は i 番目の子供が i-1 番目の子供に Xi キャンディーを与えたことを意味し、Xi<0 の場合、i-1 番目の子供が i 番目の子供に Xi キャンディーを与えたことを意味します。 Candy、X1 は、最初の子から n 番目の子に渡されたキャンディーの数を表します。したがって、最終的な答えは ans=|X1| + |X2| + |X3| + ... + |Xn| です。
一人目の子は n 番目の子に X1 個の飴をあげ、A1-X1 個の飴が残ったが、2 番目の子は X2 個の飴を与えたので、最終的に A1-X1+X2 個の飴が残る。質問の意味によると、キャンディーの最終的な数は ave に等しくなります。つまり、A1-X1+X2=ave という式が得られます。
同様に、2 番目の子の場合、A2-X2+X3=ave です。最終的に、合計で n 個の変数を持つ n 個の方程式を作成できますが、最後の方程式は最初の n-1 個の方程式から導出できるため、実際に役立つのは n-1 個だけです。
答えを直接解くことはできませんが、他の Xi は X1 で表すことができますが、この問題は単一変数の極値問題になります。
最初の子の場合、A1-X1+X2=ave -> X2=ave-A1+X1 = X1-C1 (C1=A1-ave と仮定、以下同様) 2 番目の子の場合、A2-X2+X3= ave -
> X3=ave-A2+X2=2ave-A1-A2+X1=X1-C2 すなわち C2=A1+A2-2ave=A2+C1-ave など
3 番目の子の場合、A3-X3+X4= ave -> X4=ave-A3+X3=3ave-A1-A2-A3+X1=X1-C3
Ci の一般式は Ci=Ai+C[i-1]-ave!!!!!!!!! です
。 ..
n 番目の子の場合、An-Xn+X1=ave.
Xi の絶対値の和をできるだけ小さくしたい、つまり |X1| + |X1-C1| + |X1-C2| + ... + |X1-Cn-1|できるだけ小さくしてください。|X1-Ci| の幾何学的な意味は、数軸上の点 X1 から Ci までの距離であるため、問題は次のようになることに注意してください。可能であり、この点はこれらの数値の中央値であるため、証明は省略します。