Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 12315 | Accepted: 7189 |
Description
Input
Output
Sample Input
1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0
Sample Output
1 0 1 2 3 5 144 51205
1*2的长方形木块,问组成h*w的大长方形的种数。
从第 i行放一个小木块后,可能会对下一行造成影响,但最多只会影响到下一层。
dp[i][j]代表第当1到i-1行铺满后,第i行为状态j的种数。状态j为每一行的二进制压缩1代表存在了木块,0代表不存在。在第i行遍历所有的j,对每一个状态进行dfs,找到可以填满的一种情况,得到下一行的状态。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define LL __int64 LL dp[15][2100] ; int h , w ; void dfs(int low_i,int low_j,int k1,int k2,int i) { if( i == w ) { dp[low_i+1][k2] += dp[low_i][low_j] ; return ; } if( (k1 & (1<<i)) ) { dfs(low_i,low_j,k1,k2,i+1) ; return ; } dfs(low_i,low_j,k1|(1<<i),k2|(1<<i),i+1) ; if( i+1 < w && (k1&(1<<(i+1))) == 0 ) dfs(low_i,low_j,(k1|(1<<i))|( 1<<(i+1) ),k2,i+2) ; return ; } int main() { int m , i , j ; while( scanf("%d %d", &h, &w) != EOF ) { if( h == 0 && w == 0 ) break ; memset(dp,0,sizeof(dp)) ; dp[1][0] = 1 ; m = 1 << w ; for(i = 1 ; i <= h ; i++) { for(j = 0 ; j < m ; j++) { dfs(i,j,j,0,0); } } printf("%I64d\n", dp[h+1][0]) ; } return 0; }