ntk log ntk

競プロや非競技プロのやったことを書いています.

ABC182 D - Wandering

反省.ABC3完.レート-51.

D - Wandering

解法

問題文の,箇条書きの一行で表されるまとまった動作を,ここではステップと呼ぶ.

2回累積和を取った配列から,各ステップの開始時(終了時)の座標がわかる.あとは,各ステップ内で移動できる最大値を計算しておく.これは累積和の累積MAX.(各ステップの開始時の座標 )+(各ステップで移動できる最大値)の最大値が答え.

これを理解するために(発想するために),考えたいことはすべての動作後のロボットの座標は,(各ステップの開始時の座標) + (各動作の移動距離の累積和)で表されるということ.例えば,サンプル2において各ステップの開始時の座標は,0, -2, -3, -1, 0である(手元で書くととてもよい).ステップ1において,A_1だけ動かすときは, 0 + -2 = -2にロボットがいる.ステップ4において,A_1, A_2, A_3だけ動かすときは, -1 + (-2 + 1 + 3) = -1 + 2 = 1である.

今知りたいのは,ロボットの座標の最大値なので,(各ステップの開始時の座標) + (各動作の移動距離の累積和の最大値)を各ステップで計算し,そのうちの最大値を求めればよい.

計算量はO(N)である.

コード

def main():
    from itertools import accumulate
    N = int(input())
    A = [int(i) for i in input().split()]
    S = list(accumulate(A))
    T = list(accumulate([0] + S))

    M = list(accumulate(S, func=max))

    ans = 0
    for i in range(N):
        ans = max(ans, T[i] + M[i])
    print(ans)


if __name__ == '__main__':
    main()

提出コードへのリンク

ACを取ってからだれさんのツイートについて考えてみると,より問題への見通しがすっきりとした,だれさんありがとうございます…!

類題

(最小値, 累積和)みたいなのを使う問題.アルメリアさんの記事を読んで解説ACしたけど,まだその感覚が落としこめてない….悔しい.

提出コードへのリンク


やっぱりABCを5,6完安定してできる実力が欲しい.なんとなく○○をやればいいかな~(今回だったら2回累積和を取ってみた),を実装してサンプルが合わないと思考が止まってしまうことを今からやめる!

手元でサンプルを実験して,ある程度正解である自信が得られてから実装に入りたい.また焦らずに,ていねいに考察ステップを踏むようにしたい.またすぬけさんの書いていた表がわかりやすくて,同じような表を書きたい.知りたい情報について,どう表現できるか丁寧に書くと,どこを高速化できるかわかりやすそう.

今回の内容が,考察に含まれた高難度(と言ってもABC-F)の問題もあるので,やっぱり新規ACを増やしていくことが大事.

そしてやっぱり,AtCoder青になりたいな.精進しよう.