状态压缩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 }