I - Flip Cards [TGC Edition]

2 secs 1024 MB
uni_kakurenbo's icon uni_kakurenbo

概要

動的計画法を用いて解くことのできる典型的な問題の例です.
少し複雑ですが,状態を丁寧に整理して漸化式を導いてください.

問題原案:uni_kakurenbo

解説

動的計画法を用いて解くことができます.
その一例を紹介します.

22 数列 A,BA, B はいずれも 0-based indexing とします.

  • 定義

    • DP0(i,j)(\mathrm{DP_0}(i,j) \coloneqq (先頭 i+1i+1 枚目までの裏返し方で,末尾に裏を向いたカードが jj 個連続するようなものの総数))
    • DP1(i,j)(\mathrm{DP_1}(i,j) \coloneqq (先頭 ii 枚目までの裏返し方で,末尾に裏を向いたカードが jj 個連続するようなものスコアの総和))
  • 初期状態:

    • DP0(0,0)=DP0(0,1)=1\mathrm{DP_0}(0,0) = \mathrm{DP_0}(0,1) = 1
    • それ以外はすべて 00
  • 遷移:

    • For  i[0,1,,N):\text{For} \;\,i \gets [\, 0, 1, \ldots, N\,):
      • DP0(i+1,0){DP0(i,j)1j<k}\mathrm{DP_0}(i+1, 0) \gets \sum\, \{\, \mathrm{DP_0}(i,j) \mid 1 \leq j < k \,\} #任意の枚数裏が連続 → 表
      • DP1(i+1,0){DP1(i,j)1j<k}+DP0(i,0)Ai\mathrm{DP_1}(i+1, 0) \gets \sum\, \{\, \mathrm{DP_1}(i, j) \mid 1 \leq j < k \,\} + \mathrm{DP_0}(i,0) \cdot A_i
      • For  j[1,2,,K]:\text{For} \;\,j \gets [\, 1, 2, \ldots, K\,]:
        • DP0(i+1,j)DP0(i,j1)\mathrm{DP_0}(i+1, j) \gets \mathrm{DP_0}(i, j-1) # j1j-1 枚裏が連続 → jj 枚裏が連続
        • DP1(i+1,j)DP1(i,j1)+DP0(i,j)Bi\mathrm{DP_1}(i+1, j) \gets \mathrm{DP_1}(i, j-1) + \mathrm{DP_0}(i, j) \cdot B_i
  • 結果:

    • kDP1(N,k)\sum_k \,\mathrm{DP_1}(N, k)

解説:uni_kakurenbo

実装例

C++
Python