日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

格路径计数

發(fā)布時(shí)間:2023/11/10 C# 45 coder
生活随笔 收集整理的這篇文章主要介紹了 格路径计数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

格路徑計(jì)數(shù)

基礎(chǔ)格路徑計(jì)數(shù)

問題:格路徑上從 \((0,0)\) 走到 \((n,m)\) 只能向上或向右走,方案數(shù)。

顯然一共走 \(n+m\) 次,選出任意 \(n\) 次向上走方案數(shù)就是 \(\binom {n+m} n\)。

有限制格路徑計(jì)數(shù)

下面說的限制都是不接觸到某條線的限制,若題目要求不超過,可以依次 \(+1/-1\)

單條直線限制

還是從 \((0,0)\) 走到 \((n,m)\),但在格路徑上你不能經(jīng)過 \(y=x+k\) 這條直線,求方案數(shù)。

這是卡特蘭數(shù)經(jīng)典問題,考慮把最后一次進(jìn)入直線之后的路徑后半部分翻折一下,最終終點(diǎn)也會(huì)翻折變成 \((m-k, n+k)\),總方案 \(\binom {n+m} n\) 減去不合法的部分 \(\binom {n+m} {n+k}\) 就是

\[\binom {n+m} n - \binom {n+m} {n+k} \]

兩條直線限制

還是從 \((0,0)\) 走到 \((n,m)\),但在格路徑上你不能經(jīng)過 \(y=x+k_1,y=x+k_2,(k_1>0,k_2<0)\) 這兩條直線,求方案數(shù)。

有人說直接對兩條直線分別做然后減去就行了。

但遇到一個(gè)路徑同時(shí)經(jīng)過兩條直線的情況就會(huì)算重復(fù)。

我們設(shè)兩條直線分別為 A,B,我們定義一個(gè) AB 字符串例如 BABA 表示依次進(jìn)入直線 BABA ,若多次進(jìn)入 A 或 B,只考慮第一次,也就是 ABBBAAAABBB = ABAB。

我們設(shè) \(f_{\texttt{ABAB}}\) 表示終點(diǎn) \((n,m)\) 依次對 BABA 直線進(jìn)行對稱得到的新終點(diǎn) \((n',m')\) ,然后\((0,0)\) 到新終點(diǎn) \((n',m')\) 的無限制方案數(shù)。

對于一個(gè)路徑序列代表的字符串 ABABA,我們把字符串每一個(gè)本質(zhì)不同的子段在最后一次出現(xiàn)的位置倒著依次翻折,這樣和 \(f\) 中的方案數(shù)一一對應(yīng)。

例如 ABABA 的子段 ABA,我們在最后一次進(jìn)入 A 時(shí)翻折一下,最后一次進(jìn)入 B 時(shí)翻折一下,倒數(shù)第二次進(jìn)入 A 時(shí)再翻折一下。(如下圖,三種顏色代表三次不同翻折)

我們發(fā)現(xiàn)序列 \(ABABA\) 會(huì)貢獻(xiàn)到 \(f_{\text{A}},f_{\text{B}},f_{\text{AB}},f_{\text{BA}},f_{\text{ABA}},f_{\text{BAB}},f_{\text{ABAB}},f_{\text{BABA}},f_{\text{ABABA}}\),并且貢獻(xiàn)都是 1 。

貢獻(xiàn)都是 1 是因?yàn)槲覀冎环圩詈笠淮纬霈F(xiàn)的位置,大家可以手模一下發(fā)現(xiàn)若翻折前面出現(xiàn)的位置得出的路徑和原來的不一樣。

于是不合法的方案數(shù)就變成了:

\[f_{\text{A}} + f_{\text{B}} - f_{\text{AB}} - f_{\text{BA}} + f_{\text{ABA}} + f_{\text{BAB}} - ... \]

會(huì)發(fā)現(xiàn)這樣每條直線只會(huì)被計(jì)算一次。

總方案 \(\binom{n+m}{n}\) - 不合法方案數(shù)就可以了。

多條直線限制

可以找出限制最緊的兩條變成兩條直線限制。

k-Dyck路(k階卡特蘭數(shù))

問題:還是格路徑,但是現(xiàn)在只能向上走 \(k\) 格或向右走 \(1\) 格,不超過 \(y=x\) (不接觸 \(y=x+1\))求 \((0,0)\)\((nk, nk)\) 方案數(shù)。

這是 \(k = 2\) 時(shí)的某種合法方案。

我們我們轉(zhuǎn)化為一個(gè)新問題:

只能向上走 \(k\) 格或向右走 \(1\) 格, 從 \((0,0)\)\((nk+1, nk)\) 的方案數(shù),沒有限制。

向上走的數(shù)量為 \(n\),向右走的數(shù)量為 \(nk+1\),一共 \(n(k+1) + 1\) 次,方案數(shù)顯然是:

\[\binom {n(k+1)+1} n \]

我們將新問題中的接觸到 \(y=x\) 的路徑進(jìn)行一個(gè)轉(zhuǎn)變,轉(zhuǎn)變方式如下:

首先找出在直線 \(y=x\) 上方的所有點(diǎn)(包括在 \(y=x\) 上的點(diǎn)),選擇一個(gè)距離 \(y=x\) 最遠(yuǎn)的點(diǎn)(若有多個(gè)點(diǎn)距離相同,選擇距離終點(diǎn)最近的點(diǎn)),稱之最高點(diǎn)。

將最高點(diǎn)后邊的路徑平移到 \((0,0)\),將之前從 \((0,0)\) 開始的路徑接到后面。

可以證明,轉(zhuǎn)變之后的新路徑滿足一下幾個(gè)性質(zhì):

  • 一定不會(huì)接觸到 \(y=x\)。

    • 這里很顯然。
  • 最開始一定有兩次向右操作。

    • 當(dāng)找出的最高點(diǎn)不在 \(y=x\) 上,設(shè)向右和向上分別為 \(R,U\),若這個(gè)點(diǎn)之后的操作為 \(U\) 或者 \(RU\),那么在操作后的點(diǎn)一定距離 \(y=x\) 更遠(yuǎn),最高點(diǎn)會(huì)選擇他。

    • 當(dāng)最高點(diǎn)在 \(y=x\) 上時(shí),他只有兩種可能:

      • 第一種和上面那種一樣。

      • 第二種是下一步只需要一次 \(R\) 就可以到終點(diǎn),若是這種情況,那么舊路徑的第一次操作一定是 \(R\),否則就會(huì)出現(xiàn)一個(gè)點(diǎn)在 \(y=x\) 上方,最高點(diǎn)不會(huì)選到它。

我們刪去新路徑的第一次 \(R\) 操作,終點(diǎn)變成了 \((nk,nk)\),限制變成了不超過 \(y=x\) (不接觸 \(y=x+1\)),會(huì)發(fā)現(xiàn)和舊問題中的路徑一一對應(yīng)。

新問題的新路徑和舊問題路徑一一對應(yīng),但新問題的舊路徑和新問題的新路徑并不是一一對應(yīng)的。

我們發(fā)現(xiàn)在新路徑中將任意一斷點(diǎn)截?cái)?,交換兩個(gè)部分(上述轉(zhuǎn)變的逆過程),本身的終點(diǎn)會(huì)在操作后變成最高點(diǎn),且均在 \(y=x\) 上及其上方。

這樣每一種舊路徑對應(yīng)一個(gè)新路徑,每一個(gè)新路徑對應(yīng) \(n(k+1)+1\) 舊路徑,答案就是:

\[\frac{1}{n(k+1)+1}\binom {n(k+1)+1} n \]

總結(jié)

以上是生活随笔為你收集整理的格路径计数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。