ツバサの備忘録

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

ABC092 C - Traveling Plan

問題
提出コード

解法

毎回愚直に計算するともちろん間に合わないので何か工夫をする必要があります。そこで登場するのが累積和です。
まず、始点と終点も観光スポットとみなし、A_{0} = A_{N+1} = 0としておきます。

  • s[i] = 観光スポット0からiまで順番に行ったときにかかる金額の総和

とします。
これは、
\displaystyle s[i] = \sum_{k=1}^{i} |A_{k} - A_{k-1} |
という計算をすることで求めることができます。しかし、s[i]を求めるのに、s[i-1]を利用すると、
\displaystyle s[i] = \sum_{k=1}^{i-1} |A_{k} - A_{k-1} | + |A_{i} - A_{i-1} |
であることから、
s[i] = s[i-1] + |A_{i} - A_{i-1} |
というように変形できます。
これにより、s[i]O(1)で、1からN+1すべてについてのs[i]を求めるのにO(N)で計算できるようになりました。
さて、s[i]は、観光スポット0から、という区間についてしか計算できません。[i,j]という区間についてのみ移動した場合の金額を計算するにはどうすればよいかというと、
\displaystyle  \sum_{k=i+1}^{j} |A_{k} - A_{k-1} |
という計算ができればよいので、式を変形すると
\displaystyle  \sum_{k=0}^{j} |A_{k} - A_{k-1} | -  \sum_{k=0}^{i} |A_{k} - A_{k-1} |
となります。
よって、始点を0にした計算式に置き換えることができたので、s[i]を利用して、
s[j] - s[i]
と計算すればよいことになります。

さて、下準備ができたので、i番目のスポットに行かない場合の金額の計算を行います。
このとき、移動ルートは次のようになり、それぞれ以下のようにして計算できます。

  1. [0,i-1]
    s[i-1]を参照するだけでよいです。

  2. i-1から直接i+1
    |A_{i+1} - A_{i-1}|を計算すればよいです。

  3. [i+1,N+1]
    先ほど求めたように、s[N+1] - s[i+1]を計算すればよいです。


ということで、上の3つを組み合わせ、
s[i-1] + s[N+1] - s[i+1] + |A_{i+1} - A_{i-1}|
が答えになります。これはO(1)で計算できるので、N回答えるには、O(N)かかりますが、十分間に合います。

解法

累積和入門にちょうどいいと思います。
添え字のバグにも注意しつつコードを書く必要があるのでそこだけ大変でした。