給出 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為列舉數且滿...