#毎日C問題 ABC240-C 「Jumping Takahashi」

挨拶

Rute(リュート)です。
普段は、競技プログラミングの問題を解く事、趣味の音楽ゲームをプレイすることが趣味の大学4年生です。

#毎日C問題 という企画が再開して早11日目。
皆さんは毎日連続で解けていますか?
私は大学の研究などが忙しく、毎日は解けていませんが
時間が空いた時に解いてみようと思い参加を続けています。

問題概要

問題の直接のURLは https://atcoder.jp/contests/abc240/tasks/abc240_c から

解法

TLE解法 : N回のジャンプに対してbit全探索

明らかに、N≦100であるから、動きをbit全探索などの方法で全探索する解法は実行時間制限超過(TLE)となりそうである。
より効果的に毎回の移動を処理出来る方法はないのだろうか。

AC解法:動的計画法を用いたジャンプのシミュレーション

Xより大きい座標の位置にジャンプした段階で条件である「座標Xの位置にいるようにする」ことが不可能になる
以下、考える座標は0からXまでのX+1通りとする。
また、ジャンプの回数はN回であることが分かっている。

よって、以下の様なdp(動的計画法)テーブルを作成すれば良い。

dp[i][j] = i回目のジャンプで座標jに到達しているか。
到達していれば1、そうでなければ0が入っているものとする。
0回目の移動では、座標0の位置にいることが分かっているので、
dp[i][j] に対して
i = 0かつj = 0のとき1、
それ以外の(i,j)の組においては0と初期化する。

そして、N回のジャンプのシミュレーションを行う.
i(1≦i≦N)回目のジャンプに対して、0からXまでの座標で配列の全探索を行う.
もし dp[i-1][j] = 1のとき、
i-1回目のジャンプが終了した段階で、座標jへの到達が可能である
したがって
i回目のジャンプで座標jから座標j+a[i-1]または座標 j + b[i-1]へ移動することが可能である。
(ジャンプの回数と配列の座標の位置を合わせているため、座標がそれぞれj + a[i-1]、j + b[i-1]になっていることに注意する必要がある。) 
あとは、 j + a[i-1]、j + b[i-1]がX以下かそうでないかを確認し、
X以下であるならば、
dp[i][j + a[i-1]] = dp[i-1][j]
dp[i][j + b[i-1]] = dp[i-1][j]

とdpテーブルの遷移を行う。

これをN回のジャンプに対して行うため、シミュレーションの計算量はO(NX)となり、制約内で高速に計算することが出来た。

ソースコード

感想

2/20(コンテスト当日)以来、ABC240のC問題を解いていなかった。
問題を久々に見て、N≦100、X≦10000であることから即座に動的計画法を用いる問題であると気づいた。
以前よりも高速に解法に気づいた(解いた事があるので覚えているのかもしれないが)ため、成長していると感じた。

回答時間は5分程度。
また#毎日C問題 に関してブログ記事を書ける機会があれば、解いた感想等を共有していきたいと思う。


この記事が気に入ったらサポートをしてみませんか?