#include <cstdio> #include <string> double b[13][3000]; int tran[20000][2]; int H, W, maxMove, nTran; void dfs ( int n, int from, int to ) ...{ if ( n > W ) return; if ( n == W ) ...{ tran[nTran][0] = from; tran[nTran ++][1] = to; return; } dfs ( n +2, ( from <<2 ) +3, ( to <<2 ) +3 ); dfs ( n +1, ( from <<1 ) +1, to <<1 ); dfs ( n +1, from <<1, ( to <<1 ) +1 ); } void dp () ...{ memset ( b, 0x00, sizeof ( b ) ); b[0][( 1<< W ) -1] =1; int i, j; for ( i =0; i < H; i ++ ) for ( j =0; j < nTran; j ++ ) b[i +1][tran[j][1]] += b[i][tran[j][0]]; } int main () ...{ freopen ( "in.txt", "r", stdin ); while ( scanf ( "%d %d", &H, &W ) ) ...{ if ( !H ) break; int t; if ( H < W ) ...{ t = H; H = W; W = t; } nTran =0; dfs ( 0, 0, 0 ); //pt (); dp (); //pb (); printf ( "%.0f ", b[H][( 1<< W ) -1] ); } return0; }
中等难度的DP。铺砖问题,有组合数学公式。 但是用搜索+dp的方法更……好吧,也很难做。研究了一个下午的标程,终于搞懂。把每一层的砖块压缩为二进制编码,搜索上一层到当前层的状态转化是否能够达到。然后从0到11……11Dp。void dfs ( int n, int from, int to ) 表示当前从左往右有n块砖,from表示前n块砖在这一层的编码,to表示下一层。修改了一下,使得1