铺地砖 状态压缩DP

状态压缩DP   铺地砖
题意 用 1*2 的 小块将n*m的方块填满,问有多少种方案

如果一个地方能够横放就横放,因为竖着是一定能放的

 

 1 #include <bits/stdc++.h> 
 2 #define LL long long 
 3 #define For(i,j,k) for(int i=j;i<=k;i++) 
 4 using namespace std ; 
 5 
 6 const int N = 1011 , mod = 1000000007 ; 
 7 int n,m,all,full ; 
 8 int dp[N][1026],bin[13] ;  
 9 
10 int main() 
11 {
12     bin[ 0 ] = 1 ; 
13     For(i,1,10) bin[ i ] = bin[i - 1] * 2 ; 
14     while(~scanf("%d%d",&n,&m)) { 
15         memset(dp,0,sizeof dp) ; 
16         full = bin[m]-1 ; 
17         all = bin[m<<1]-1 ; 
18         dp[ 1 ][ 0 ] = 1 ; 
19         For(i,1,n) {
20           For(k,1,m) 
21               For(j,0,all) 
22                   if( (j&bin[k-1])==0 ) {
23                       if( k!=m&&(j&bin[k])==0 ) 
24                           dp[i][ j | bin[k-1] | bin[k] ] = ( dp[i][ j | bin[k-1] | bin[k] ] + dp[i][j] ) % mod ; 
25                       dp[i][ j | bin[k-1] | bin[k-1+m] ] = ( dp[i][ j | bin[k-1] | bin[k-1+m] ] + dp[i][j] ) % mod ; 
26                 }
27             For(j,full,all) 
28                 if( (j&full)==full) 
29                     dp[i+1][j>>m] = dp[i][j] ;   
30         }
31         printf("%d\n",dp[n][full]) ;         
32     }
33     return 0 ; 
34 }

 

posted @ 2017-08-18 14:38  third2333  阅读(511)  评论(0编辑  收藏  举报