Question: How many paving methods are there to store the same I-and L-type floor tiles on the M * n floor.
Analysis: DP, combination, and count. Classic DP problems, status compression. Like zoj1100, there are only a few more States.
Status: If f (I, j) is filled with the front I-1, the bit of the I row is represented as the number of paving types when J;
Transfer: I-type bricks, because they can only be horizontal or vertical, there are only two statuses before a brick is paved;
If the current vertical bar is placed, the next row will be affected, and the State correspondence between the two adjacent rows will be established;
L-type brick, because it will certainly affect the two layers, a total of four placement methods, the establishment of adjacent Zeng relationship;
Here we can use DFS to find all the front States F (I-1, k) Addition of the last line of all f (I, j;
F (I, j) = sum (f (I-1, k) {Where F (I-1, k) can generate f (I, j) status };
(The storage status is prepared, but MLE is used, so the last side is extended while the other side is added .)
Note: Only Use % i64d, which is the opposite of zoj. ).
#include <stdio.h>#include <stdlib.h>#include <string.h>long long F[ 10 ][ 1<<9 ];//用dfs找到可以到达本状态的上层的状态 void dfs( int A, int B, int C, int D ){ if ( !A ) { F[ C ][ D ] += F[ C-1 ][ B ]; return; }else { int V = A&-A;//取得最后一个 1的位置 if ( B&V ) { dfs( A&~V, B&~V, C, D ); //竖着放 1*2 if ( V>1 && (B&(V>>1)) ) dfs( A&~V, B&~(3*(V>>1)), C, D ); if ( B&(V<<1) ) dfs( A&~V, B&~(3*V), C, D ); } if ( A&(V<<1) ) { dfs( A&~(3*V), B, C, D ); if ( B&V ) dfs( A&~(3*V), B&~V, C, D ); if ( B&(V<<1) ) dfs( A&~(3*V), B&~(V<<1), C, D ); } }}int main(){ int n,m; while ( scanf("%d%d",&n,&m) != EOF && m ) { if ( m>n ) {int t = m;m = n;n = t;} int M = (1<<m)-1; for ( int i = 0 ; i <= n ; ++ i ) for ( int j = 0 ; j <= M ; ++ j ) F[ i ][ j ] = 0LL; F[ 0 ][ M ] = 1LL; for ( int i = 1 ; i <= n ; ++ i ) for ( int j = 0 ; j <= M ; ++ j ) dfs( j, M, i, j ); printf("%I64d\n",F[ n ][ M ]); } return 0;}
Sgu 131-hardwood floor