ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

AGC027 B - Garbage Collector

問題
提出コード

解法

ゴミを回収しに行く回数(=ゴミを捨てる回数)をk回と決め打ちし、そのときの最小値を求めます。
そして、最後にkについて全探索して答えを求めることを考えます。
k回ゴミを回収しに行くとき、ゴミを拾う回数はn回、捨てる回数はk回なので、(n+k)×x足す必要がありますが、これは値がkにしか依存しない(他が定数)ので、これ以降は考えないことにして、最後に足します。
今、1回の収集でp個のゴミを拾うことについて考えます。
少し実験するとわかるのですが、ゴミを回収する際は、できるだけ遠い場所に行き、その帰り道にゴミを回収していくのが最も効率がいいです(これは、手持ちのゴミが多いと消費エネルギーが多くなるためです)。
左からi番目のゴミをj番目(1~p)に回収するとき、増加するエネルギーについて考えると、

  • j=1のとき
    x_iに向かうのにエネルギーをx_i、そこからゴミを回収して原点に帰るのにエネルギーを4×x_i消費します。合計で
    5×x_i
    消費します。

  • j \neq 1のとき
    x_iから帰るときの消費エネルギー(1+y)^{2}×x_iは、j-1以下までの計算である程度計算されています。
    ので、足りない分を追加してあげる必要があります。
    (1+y)^{2}は、yが1増えると2×y+1だけ増加します。今、j-1以下で(1+j-1)^{2}まで計算されているので、(1+j)^{2}にするために2×j+1だけ増加させます。ということで、増加エネルギーは
    (2×j+1)×x_i
    となります。


ということで、上記の式を用いて計算することで、p個のゴミを1度に回収する場合の消費エネルギーを求めることができるようになりました。
さて、p個のゴミの決め方、およびk回回収するなかでのゴミの個数の振り分け方を考えます。
先ほどの式を見るとわかるように、pの個数が多いほど、消費エネルギーを計算する回数が増えるので、それだけ消費エネルギーが増加してしまいます。なので、1回あたりの回収する個数はできるだけ少なくしたいです。ということで、平均的にする必要があります。
また、距離が遠いほど、消費エネルギーはもちろん多くなります。なので、ここにかかる係数(具体的には5、もしくは(2×j+1)です)を小さくしたいです。なので、遠いゴミは、同時に拾うのをできるだけ避けたいです。
ということで、

  • できるだけ1回あたりに拾う個数を平均的に

  • 遠いゴミを同時に回収することを避ける

とすると、次のように回収することになります。
n, n-1, ... n-k+1番目 のゴミは、k回回収するなかでそれぞれ1番目(手元にゴミがない状態のとき)に回収
n-k, n-k-1, ... n-2k+1番目のゴミは、それぞれ2番目(手元にゴミが1個の状態のとき)に回収
と続いていきます。端数が発生した場合、とくに気にせず足していきます(その端数分で1つのくくりにします)。
つまり、ゴミを遠い方から順番にk個ずつ選び、そのまとまりごとに1番目に回収、2番目に回収、としていくと、kを固定したときの最適解となります。
これをもとにして、上で述べたような5×x_iおよび(2×j+1)×x_iの式に当てはめていくのですが、x_iの部分を、j番目に回収するゴミをまとめて一気に処理する方法があります。累積和です。
sum[i]=i番目までのx_iの総和
とすると、
たとえば1番目に回収、すなわち5×x_iの式に当てはめるものは、n-k+1nについてのx_iなので、
sum[n] - sum[n-k]
となります。これをx_iの部分に代入してあげれば、まとめて処理できます。
あとは、これを計算していった結果と、(n+k)×xの和を求めれば、kを決め打ちしたときの最適解になります。
5×(sum[n] - sum[n-k])+(2×j+1)(sum[n-(j-1)k]- sum[n-jk])
+(n+k)×x
となります(jは2以上です)。
あとは、kについて全探索して、最小値を求めれば、答えが求まります。