Typical DP Contest G - 辞書順
解法
まず、
- 文字目の次にという文字が現れるインデックスの最小値
を計算します。
これは、という更新を行えばよいです。
さて、
- 文字目を先頭で使った際にできる、部分文字列の種類数
というDPを考えます。
文字目を使った際に考えられるパターンは、
文字目の1文字のみ
文字目の次に、という文字を繋げる
の2つです(後者は最大26通りありますが…)。前者は明らかにトータル1通りです。
後者については、の直後に現れるを取ってくると、番目の文字の次にを置いたパターンの部分文字列が網羅できます。
なので、結局
という遷移になります。
では、最終的に求めたい文字列はどうなるでしょうか。
まず、先頭の文字がa,b,...z
であるような部分文字列全てについて足してもにならない場合は、明らかにEel
となります。
それ以外の場合は、前から貪欲、a
から順番に見ていき、総和が以上になるならその文字を選択…という操作を繰り返します。
実装の際は、先頭にダミーの文字を入れると実装が少し楽になります。
今見ているインデックスをとして、次に選ぶ文字をa
から順番に見ていきます。を見て、これが以上ならばが次の文字になります。そうでなければ、からを引き、次の文字をチェックしていきます。
今見ている文字が最後の場合となるパターンをから引き忘れないようにすれば、答えが求まります。
感想
最近ABCやその他の場所で、ある状態を構成し数え上げる際に重複するパターンを、貪欲にチェックする操作のみ考慮することで重複を消す、という考え方を使ってきたので、それと似たような考え方でできました。
それよりむしろ、メモリ制限が厳しかったです…空間計算量はまだまだ難しいですね