形式
無限制
最簡單的一種。
- 從 \((0,0)\) 走到 \((n,m)\),每次只能向上或向右走,一共有 \(\dbinom {n+m} n\) 種方案。
不碰線格路計數問題
問題:從 \((0,0)\) 走到 \((n,m)\),每次只能向上或向右走,且不能碰到直線 \(y=x+1\),問有多少種方案。
考慮容斥,總方案數為 \(\dbinom {n+m}n\) 種。
考慮第一次碰到直線後,把後面的路徑按 \(y=x+1\) 對稱一下,相當於走到 \((n-1,m+1)\)。
發現走到 \((n-1,m+1)\) 既是充要的,又是必要的,所以碰到直線的方案數就是 \(\dbinom {n+m} {n+1}\)。
雙不碰線格路計數問題
問題:從 \((0,0)\) 走到 \((n,n)\),不能碰到直線 \(y=x-1\) 和直線 \(y=x+k\)(顯然兩條直線平行),求方案數。
還是容斥,總方案數為 \(\dbinom {2n} n\)。
減去分別碰到 \(y=x-1\) 和 \(y=x+k\) 的方案數,但是如果兩條都碰呢?
考慮再加上先碰 \(y=x-1\) 再碰 \(y=x+k\) 的,以及先碰 \(y=x+k\) 再碰 \(y=x-1\) 的。
一直這樣算下去,直到超出可行範圍內。
應用
Catalan number
定義卡特蘭數 \(C_n\) 為從 \((0,0)\) 走到 \((n,n)\) 且不碰到直線 \(y=x+1\) 的方案數。
容易算出
運用模型:
-
長度為 \(2n\) 的合法括號序列數。
-
\(1,2,...,n\) 依次入棧,合法出棧序列數。
-
\(n\) 個點的無標號有根二叉樹數量。
-
\(n\) 邊凸多邊形的三角剖分方案數。
根號分治
- 題目:有兩個人,從 \((0,0)\) 走到 \((n,n)\),每一步都同時走,全程兩人之間的曼哈頓距離不超過 \(2k\),求方案數。
發現同時向上/右走不影響兩人之間的距離,考慮列舉異方向走的步數 \(d\)。
-
第一個人向上走,第二個人向右走,距離 \(+2\)。
-
第一個人向右走,第二個人向上走,距離 \(-2\)。
相當於一個變數,每次 \(+1\) 或 \(-1\),操作 \(2n\) 次,最後變為 \(0\),全程都在 \([-k,k]\) 內。
放在平面上,從 \((0,0)\) 走到 \((n,n)\),不能碰到 \(y=x-k-1\) 和 \(y=x+k+1\)。
反射容斥,雙不碰線問題,答案為 \(\dbinom {2n} n - 2\dbinom {2n} {n-(k+1)} + 2\dbinom {2n} {n-2(k+1)} ...\)
這樣算複雜度為 \(O(\dfrac {n^2} k)\)。
我們可以 DP,複雜度為 \(O(nk)\)。
根號分治,\(O(n\sqrt n)\)。
LIS \(\le 2\)
問題:求有多少個排列 \(p\),滿足 LIS \(\le 2\)。
考慮取反,最長下降子序列長度 \(\le 2\)。
根據 Dilworth 定理,最大反鏈等於最小路徑覆蓋,即排列 \(p\) 可以被劃分為兩個上升子序列。
- 一個很牛逼的 DP:設 \(f[i,j]\) 表示填寫了 \(p_{1...i}\),最大值為 \(j\) 的合法方案數。
考慮轉移到 \(i+1\),下一個填的數可以比 \(j\) 大:\(f[i+1,k]\gets f[i,j] (k>j)\)。
否則一定填 \(<j\) 的沒填的最小數字,如果不填最小,那麼之後填這個最小數字會產生一個長度為 \(3\) 的下降子序列。
這樣轉移為 \(f[i+1,j]\gets f[i,j]\)。
那麼 \(f[i+1,j...n]\gets f[i,j]\)。
考慮轉格路計數問題,相當於從 \((0,0)\) 走到 \((n,n)\),不能碰到 \(y=x-1\),其實就是 \(C_n\)。