“k車問題”&動態規劃

最近開始做算法題,準備堅持至少一年。解決完問題可能會來記錄一下。
嗯,正式開始之前順便說說今天的上課的一個細節,權當日記:
上計算機網絡的時候,我和旁邊的同學討論我原創的一個算法題。
前面的同學:“你們倆能不能別吵了?”
面對這個學巨,我內心非常慚愧。
然後…
他趴在桌上睡着了…睡着了….

好的,廢話說完,進入正題,講講我吵到前面這位同學睡覺時討論的那道題。
這個問題是我再思考八皇后的問題時想到的,實際上,我誤以爲皇后不能斜着走,跟中國象棋中的車一樣,結果就成了八皇后問題的弱化版。

在中國象棋棋盤上有10行9列兵線,現在考慮在棋盤上放k<9個車,使他們互相之間不能吃掉對方,問有多少種方法?如果把棋盤改成m×n的呢?

下面是思路:
f(k,n,m) 爲k個車放到n×m棋盤上的方案數(k<=min{m,n})
爲了避免重複計算,按行爲主序排序這m×n個位置。假設選中第一個放車的位置爲(i,j) ,那麼前i行和第j列不能再放其他車:第i行和第j列顯然不能再放,至於前i-1列爲什麼不能再放,是因爲如果放了,它就排在(i,j) 前面,(i,j) 就不是第一個選中的位置了。接下來能放車的位置如下圖陰影區域所示。

這裏寫圖片描述

剩下k-1個點先從左側陰影區選p(0pk1 )個,有f(p,n-i,j-1)種方案。剩下k-1-p個點從右側陰影區選擇,有f(k-1-p,n-i-p ,m-j)種,第二個參數爲什麼有個-p請自己思考。
至此我們已經可以寫出狀態轉移方程

f(k,n,m)=i=0nj=0mp=0k1(f(p,ni,j1)+f(k1p,nip,mj))

邊界是當k==0||n==0||m==0||k>m||k>n 時,f(k,n,m)=0.
這樣,聲明一個狀態數組,利用動態規劃就能解出結果。
上述表達式還可以優化,i和p的遍歷的上界還可以更精確。比如注意到要是剩下的k-1個點能放入陰影部分,必須有nik1

上面的問題與下面這個問題完全等價:
集合A={123...n},B={1,2,3...m}.C=A×B. 從C中取出k個元素(xi,yi),1ik ,使得1ijk ,有xixjyiyj ,共有多少種方案?要求寫程序輸入 n,m,k,輸出方案數。
按照k車問題的背景很容易想到按行爲主序遍歷第一個選中位置而進一步計算所有情況。那麼同樣地,在這種純數學的表述下,也應該定義一個偏序關係(xi,yi)<(xj,yj) 爲C中的元素排序。仿照上面的思路,這個偏序關係可以以第一個元素的大小爲主序。

程序等有空再放吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章