1. 程式人生 > 實用技巧 >51nod 1327 棋盤遊戲

51nod 1327 棋盤遊戲

原題連結

51nod 1327 棋盤遊戲

題意

  • 給定一個 \(n \times m\) 的棋盤
  • 給定每行一個左區間 [1, L[i]] 和一個右區間 [m - R[i] + 1, m]
  • 每列有且僅能有一顆棋子, 每個左區間有且僅有一顆棋子, 右區間有且僅有一顆棋子
  • 保證每一行的左右區間不相交

求合法方案數

解題報告

這題挺妙的, 雖然可能妙得不是非常直觀

首先, 因為考慮每一列只能填一個, 考慮怎麼填

宣告 l[i] 為以 i 為左區間右端點的行數, r[i] 為以 i 為右區間左端點的行數, mid[i] 為第 i 列上有多少沒有被左右區間覆蓋的行數

於是可以設計一個狀態 f[i][j][k]

表示當前考慮到了第 i 列, 有 j 列沒填, k 行左端點 \(\le i\) 的右區間沒有填任何棋子的方案數

則能夠考慮第 \(i + 1\) 列的棋子填在哪裡, 而且每次讓左區間強行滿足條件, 即左區間右端點 \(\le i\) 的每一個左區間都有且僅有一顆棋子

有:

\(i + 1\) 列的棋子被左區間覆蓋:

\[f[i + 1][j - l[i + 1] + 1][k + r[i + 1]] += f[i][j][k] \times A_{j + 1}^{l[i + 1]} \]

\(i + 1\) 列的棋子被右區間覆蓋:

\[f[i + 1][j - l[i + 1]][k + r[i + 1] - 1] += f[i][j][k] \times A_{j}^{l[i + 1]} \times (k + r[i + 1]) \]

\(i + 1\) 列的棋子沒有被左區間或右區間覆蓋:

\[f[i + 1][j - l[i + 1]][k + r[i + 1]] += f[i][j][k] \times A_{j}^{l[i + 1]} \times (mid[i + 1]) \]

然後最後答案就是 $$\max\limits_{i = 1 \cdots m} f[m][i][0]$$ 了