DLX 精確覆蓋 重複覆蓋

2021-07-10 10:45:01 字數 1997 閱讀 8072

給定乙個n*m的矩陣,有些位置為1,有些位置為0。如果g[i][j]==1則說明i行可以覆蓋j列。

problem:

1)選定最少的行,使得每列有且僅有乙個1.

2)選定最少的行,使得每列至少乙個1.

這類屬於np問題的問題,可以使用搜尋解決。但是普通的搜尋必超時無疑。因此我們要設法加優化來加快速度。

dancing links從資料結構方面對此類搜尋進行了優化,通過僅保留矩陣中有用的部分提高了搜尋速度。dlx的儲存結構採用迴圈十

字鍊錶,在搜尋過程中不斷將不需要的部分切

除,隨著迭代深度的增加,矩陣迅速變得稀疏。

甚至一些你想不到的優化,dlx都替你想好了。

對於problem1)的解:

dlx 精確覆蓋對於當前矩陣的處理是,首先將當前要覆蓋的列以及使得能夠覆蓋到該列的行全部去掉,然後再逐行列舉新增的方

法。這是由其「有且僅有乙個1」的條件 決定的。

列舉某一行r,則設定當前列的解為該行r,那麼該行能夠覆蓋到的列必然全部都可以不必再搜,因此將該行r覆蓋到的列全部去掉。

又由於去掉的那些列 都相當於已經有了解,

那麼能夠覆蓋到那些去掉的列的行也應當全部去掉。

搜完之後記得resume。

對於problem2)的解:

dlx 重複覆蓋對於當前矩陣的處理是,將當前列去掉,並將選作當前列的解的行能夠覆蓋到的列全部去掉。因為不需要每列僅由一

個1去覆蓋,因此不必要把能夠覆蓋某 一列的

所有行全部去掉。因此remove和resume函式的寫法將會有所不同(獸家在這裡糾結了

一會兒= =)。這是與problem1)的第乙個區別。

第二個區別是,由於矩陣密度下降會變慢(因為去掉的少了),因此要加上乙個強剪枝。這個 剪枝利用的思想是a*搜尋中的估價函

數。即,對於當前的遞迴深度k下的矩陣,估

計其最好情況下(即最少還需要多少步)才能出解。也就是,如果將能夠覆蓋當 前列

的所有行全部選中,去掉這些行能夠覆蓋到的列,將這個操作作為一層深度。重複此操作

直到所有列全部出解的深度是多少。如果

當前深度加上這個估價函式返 回值,其和已然不能更優(也就是已經超過當前最優解),則直接返回,不必再搜。(其實平時的搜 索

也會不自覺地使用這個剪枝思想吧)。

採用靜態鍊錶,不過也不需要記憶體池。使用l,r,d,u四個陣列記錄某節點上下左右鄰居為誰。使用s記錄某列有多少個節點。更新思

想同鍊錶。remove之 後會產生一些孤立節

點。這看上去不怎麼好。但是我們就是要利用這些孤立節點來完成優化。比如刪掉節點i,

則l[r[i]] = l[i],r[l[i]] = r[i]。這樣i這個節點被孤立掉。但是後面resume的時候使用如

下語句:l[r[i]] = i,r[l[i]] = i。巧妙地「變廢為

寶」。對於深度k下當前列的選擇,採用選擇1的個數最少的決策。這是顯然的。hdu2295的試驗表明,隨便選一列將近800ms,而採用這

個策略將達到500ms。不過對於當前列的選

擇,還是要根據具體情況確定。有時候你的**比別人慢,很可能就是因為這個列的選 擇。

problem1) :

hust1017 **dlx精確覆蓋。

problem2):

hdu2295 二分+dlx重複覆蓋。

dancing links**中講到的一題,並以此為基礎使另外一些型別的題目轉化為此種精確區間覆蓋模型用dlx解決。

深搜:1、如果矩陣為空,得到結果,返回

2、從矩陣中選擇一列,以選取最少元素的列為優化方式

3、刪除該列及其覆蓋的行

4、對該列的每一行元素:

刪除一行及其覆蓋的列,

5、進行下一層搜尋,如果成功則返回

6、恢復現場,跳至4

7、恢復所選擇行

用雙向十字鍊錶來維護該矩陣,方便刪除與恢復,其中刪除操作:

r[l[i]]=l[i];

l[r[i]]=r[i];

恢復操作:

r[l[i]]=i;

l[r[i]]=i;

SPOJ 1771 DLX精確覆蓋,重複覆蓋

dlx的題,做過這題才算是會吧。這道題轉化成了精確覆蓋模型來做,一開始,只是單純的要覆蓋完行列和斜線,wa。後來醒悟了,不能這樣,只要覆蓋全部行或列即可。雖然如此,但某些細節地方很關鍵不能考慮到。特別要注意的是 for int i r c i i r i 找最小值只能是在ne之前,為什麼呢?因為我們...

DLX 精確覆蓋問題

精確覆蓋問題 給定乙個由0 1組成的矩陣,問是否能找到乙個行的集合,使得集合中每一列都恰好包含乙個1 如圖 演算法x 通過dfs,每次選取一行可行 模擬演算法x過程 很容易想到上面的搜尋,但是狀態的改變很難操作,包括了刪除和復原,使用普通的資料結構運算根本停不下來。於是,一位大師想到了神奇的資料結構...

poj 3740 DLX(精確覆蓋)

題意 經典的精確覆蓋問題。思路 精確覆蓋問題是npc的,用dlx能夠比較有效的搜尋。寫完兩個數獨再寫這個就不難了 實際上這個是原始問題,數獨只是dlx的應用 include include define n 16 define m 300 struct nodep n m m 5 int s n 5...