鋪瓷磚 狀壓dp經典問題

2021-09-16 12:57:03 字數 1541 閱讀 7467

給出 n×m的矩形方塊,可以往上面鋪1×2的磚塊,問鋪滿這個方塊的方案有多少種。

磚塊可以豎鋪和橫鋪,豎鋪的話會影響到下一行,橫鋪的話不會影響到下一行,這裡我們令1:表示該方塊不會影響下一行,0:表示該方塊會影響下一行。

條件一:

考慮(i.j)這一格,如果(i-1,j)上是0,那說明(i-1,j)是豎鋪的磚塊,那麼(i,j)便是1,該點不會影響到下一行了。若(i-1,j)1,那麼(i,j)可以是0也可以是1。從而可以得知(i,j) | (i-1,j) = 1

條件二:

只有這個條件還是不夠的,因為一旦(i-1,j)是橫鋪的話,那麼(i-1,j+1)也是1,現在考慮初始狀態,001100,因為第一行是不會有上一行影響他的,所以如果該點時1那麼其必定是橫鋪。根據橫鋪的性質,必定有兩個連續的1,所以我們可以得出第一行合法的狀態有哪些。例如010101便是不合法的。

得出了第一行合法的狀態後,列舉第二行的狀態,首先要滿足的便是條件一,其次考慮條件二,因為第二行是會受上一行影響的,所以如果第二行出現(i,j)出現1那不一定是橫鋪的磚塊,因為如果上一行是(i-1,j)0的話,那麼(i,j)已經被覆蓋了且不會影響下一行。

仔細觀察的話可以發現。如果(i-1,j)1同時(i,j)也是1的話那麼該處一定是橫鋪。所以只需兩行狀態相與(&)為1的點便是橫鋪,然後便可以判斷是否合法(這裡有個優化的地方,便是可以預處理出合法的狀態有哪些)。

最終一行的答案必須全是1,因為其沒有下一行可以影響了。

#include

using

namespace std;

const

int mod =

1e9+7;

int n,m,mark[

1<<11]

;int dp[

105][1

<<11]

;void

init()

} k >>=1;

}if(flag)

dp[1]

[i]= mark[i]=1

;}}int

main()

}}cout << dp[n]

[tot-1]

<< endl;

return0;

}

鋪瓷磚 狀壓dp

最近學了狀壓dp,把之前未解決的題目捋一捋。這是之前的一道題 今天蒜頭君裝修新家,給家裡買了一種 1 2或2 1 的長方形 如圖1 新瓷磚。蒜頭君是個懂得審美的人,畢竟人生除了金錢,還有詩和遠方。這個時候蒜頭君就在想,這種長方形的瓷磚鋪到乙個 10 10 10 times 10 10 10 的地面上...

狀態壓縮dp(鋪瓷磚問題)

今天蒜頭君裝修新家,給家裡買了一種 1 times 21 2的長方形 如圖1 新瓷磚。蒜頭君是個懂得審美的人,畢竟人生除了金錢,還有詩和遠方。這個時候蒜頭君就在想,這種長方形的瓷磚鋪到乙個 10 times 1010 10 的地面上有多少種方案?如圖2 是 4 times 44 4 地面的一種方案 ...

POJ 1185 經典狀壓dp

做了很久的題 有注釋 include include include include includeusing namespace std int dp 107 107 107 二維記錄上一次 三維記錄此次 dp i k j max dp i k j dp i 1 t k num j t為列舉數且滿...