狀態壓縮 二 Hiho9 Hihocoder

2021-06-26 17:52:24 字數 3091 閱讀 1259

歷經千辛萬苦,小hi和小ho終於到達了舉辦美食節的城市!雖然人山人海,但小hi和小ho仍然抑制不住興奮之情,他們放下行李便投入到了美食節的活動當中。美食節的各個攤位上各自有著非常多的有意思的小遊戲,其中乙個便是這樣子的:

小hi和小ho領到了乙個大小為n*m的長方形盤子,他們可以用這個盒子來裝一些大小為2*1的蛋糕。但是根據要求,他們一定要將這個盤子裝的滿滿的,一點縫隙也不能留下來,才能夠將這些蛋糕帶走。

這麼簡單的問題自然難不倒小hi和小ho,於是他們很快的就拿著蛋糕離開了~

但小ho卻不只滿足於此,於是他提出了乙個問題——他們有多少種方案來裝滿這個n*m的盤子呢?

值得注意的是,這個長方形盤子的上下左右是有區別的,如在n=4, m=3的時候,下面的兩種方案被視為不同的兩種方案哦!

小ho的觀察力一向不錯,這不,他很快便發現了m的取值範圍只可能為3、4、5三種情況,但是這一發現並沒有能夠給他減輕多少煩惱。

雖然在過去一段時間的訓練下,小ho很快就意識到這道題目可能仍然是需要使用動態規劃進行解決,但是他苦思冥想也沒有能夠想到很好的狀態定義方式:「如果我每次列舉一塊蛋糕的放置位置,那麼我就需要儲存下整個盤子的放置情況——也就是說2的(n*m)次方種狀態,存不下呀存不下!」

小hi看著小ho憋悶的樣子,也是知道他想錯了方向,於是道:「你先別急,讓我們從頭來看看這個問題,首先你先告訴我,我們的問題是甚麼?」

小ho搖了搖頭,想了想,道:「有多少種方案可以用1*2的正方形填滿乙個n*m的長方形?」

小hi笑道:「是的,我們不妨稱這個答案為sum(n, m),那麼我們接下來要做的事情是不是要想辦法把這個問題分解成若干子問題呢?」

小ho道:「是的,我之前也是想到這裡,我首先列舉一塊蛋糕的放置位置,那麼剩下的空閒位置有多少種方案被填滿就是乙個子問題了!由於這個位置的數量是在一直減少的,所以我可以按照一定的順序依次求解出所有這樣的問題的答案,但是這樣的問題的數量太多了,根本計算不過來。」

小hi道:「你可是想的太簡單了呢,真的只有算不過來的問題麼?你且看這兩種情況,雖然我第一次列舉的位置不同,但是只要第二次列舉的是另一種情況的第一次列舉,那麼最終都會到達同樣的狀態,那麼接下來是不是就會出現重複的統計啊?」

小hi笑道:「我有一計,可解上述兩大難題!」

小ho道:「快快道來!」

小hi揮揮手,表示不要著急,接著說:「你看!對於這樣一種方案,按照你之前的方法,無論是1234的順序列舉,還是4321的順序列舉,最後統計到的都是這樣一種方案,也就是無論是1~4的哪一種排列,都會是這樣的方案,那麼是不是說明,每一種方案都被統計了(n*m)!次?」

小hi滿臉無奈道:「真是個沒志氣的傢伙,你為什麼不乾脆想辦法使得每種方案都只被統計一次呢?」

小ho:「怎麼做?!教教我~」

小hi道:」你想想,既然無論以什麼樣的排列順序都會致使同樣的結果,那麼我們就想辦法給它定義乙個順序便是了呢?比如說,對於每一塊蛋糕,以其左(上)邊一塊的行號為第一關鍵字,列號為第二關鍵字的順序,只有按照這個順序遞增的排列才是合法的!」

小ho低頭算了算,道:」是的!這樣就只有1234這樣一種順序合法了,同樣的,其他的每一種方案也都會只有一種對應的方案。但是我仍然不懂的是,我怎麼保證在求解這個子問題的時候,一定能夠只搜尋出這樣的方案呢?「

小hi道:」這個簡單!只要不是列舉每一塊蛋糕放在什麼地方?而是按照行號為第一關鍵字,列號為第二關鍵字的順序,依次列舉每個位置上的蛋糕是如何放置的!通過這樣的方式,來將乙個問題分解成子問題!比如在下面的這個問題中,我當前要決定的便是黑色方塊的蛋糕放置方案,而不同的放置方案——橫放還是豎放,便會匯出不同的子問題,並且這樣是不會像之前的方法那樣,有重複統計的。」

「唔……其實好像只用記錄兩行就可以了!因為在列舉到(i, j)這個位置的時候,也就是當前列舉的位置所在的這一行,以及下一行。因為這之前的位置肯定都已經放置滿了蛋糕,而這之後的位置肯定都還沒有放置任何東西!」小ho恍然大悟道。

「那你準備如何定義狀態呢~」

「像這樣,我令sum(i, j, p1, p2, ... , pm, q1, q2, ... , qm)表示:已經將第一行至第i-1行的盤子都已經填滿了,當前正在嘗試往(i, j)這個位置放置蛋糕,而第i行的放置情況用p1...pm表示,第i+1行的放置情況用q1...qm表示——0表示為空,1表示放置了蛋糕。那麼sum(i, j, p1, p2, ... , pm, q1, q2, ... , qm)便表示在這種情況下,剩餘的格仔有多少種填充的方法,而我們要求的問題便是sum(1, 1, 0, 0, 0, ..., 0)了!」

小hi笑道:「誒,你居然注意到了這個問題要求的是sum而不是best~這並不像之前的動態規劃一樣是求乙個全域性最優解,而是單純的統計方案數!」

小ho拍拍胸脯道:「你也不看看我是誰!而我覺得轉移會是這樣的……其中第

一、二種情況是用於當前位置並不是空白位置時;第三種到第六種分別代表著當前位置的蛋糕擺放方向的2*2種可能。」

檢視大圖

小hi點了點頭,道:「沒錯!那你有沒有覺得你這樣的狀態定義還是沒有辦法很好的根據m來進行轉移?」

小ho驚道:「是的呢!對了!我們還可以用上一周說的那種「狀態壓縮」的方式,將p1 ... pm, q1 ... qm 這2m個0/1表示成為乙個整數,這樣我的狀態轉移方程就會變成這樣了!其中si表示s轉換為2進製後從高到低第i位的值~」

檢視大圖

「是的呢!」小hi點了點頭:「趕緊去寫個程式算出來,我們就可以去吃蛋糕了!」

hiho 9 狀態壓縮二

歷經千辛萬苦,小hi和小ho終於到達了舉辦美食節的城市!雖然人山人海,但小hi和小ho仍然抑制不住興奮之情,他們放下行李便投入到了美食節的活動當中。美食節的各個攤位上各自有著非常多的有意思的小遊戲,其中乙個便是這樣子的 小hi和小ho領到了乙個大小為n m的長方形盤子,他們可以用這個盒子來裝一些大小...

狀態壓縮二 (hiho 1048)

題意 給出乙個n m的矩形格仔,用2 1的塊去填滿塊的方案數。2 n 1000,3 m 5 思路 由於m比較小,可以用位對其進行記錄,矩形內1 1的格仔的狀態有 橫著的開始,橫著的結尾,豎著的開始,豎著的結尾,所以用0,1,2,3 來分別進行表示,這樣用乙個2bit即可。為了加速,先把不可能的一些狀...

hiho 1048 狀態壓縮2

題目大意 用1x2的單元拼接出 nxm的矩形,單元可以橫放或者縱放,n 1000,m 5.求不同的拼接方案總數。分析 實現 include include include using namespace std define bit i,j i 1 j 1 const int mod 1000000...