sicily Tiling a Grid With Dominoes

来源:互联网 发布:vb datagrid增加列 编辑:程序博客网 时间:2024/05/16 08:57

题意:
问一个 L*4 的矩形,用2*1的小矩形组成有多少种组法。

思路:
递推。用一个4bit的整数表示“行状态”。写出15个递推式即可。

首先,定义 f [ i ] [ j ] 为, 已组成长度 (i - 1)* 4 的完美矩形, 第 i 行的状态是 j (0~15)的方案数。那么我们可以考察 f [ i ] [ j ] 可以怎么求得。

注意下面的状态方程的推导,围绕的思路不仅是要填满 15(1111) 这个“满”状态,而是要填满所有1~15的状态( i 行才能根据 i - 1 行转移),所以2情况和5情况,不是重复的,动态规划里所有的一切都是围绕“状态”的概念来展开。

1、【竖放】首先,如果在 i - 1 行有缺某些位,放上一块(竖着放)之后, i-1行的该位被填上,而i行的该位会突出,状态码刚好是对15(1111)取补。例如
这里写图片描述

2、【横放】假设 i - 1 行已经完美覆盖,那么我们总可以在 i 行 横放 1块或2块积木来得到新的状态。例如
这里写图片描述

f [ i ][ 6 ] 、 f [ i ][ 12 ] 与 f [ i ][ 3 ] 情况类似,图就不赘画了。

3、 如果经过前述 i 行 有突出一个位的, 我们还可以通过横放一个积木补上来将其填得更满,例如:
这里写图片描述

注意是在同一行(i行)横放积木,所以第一个下标全是 i , 其余情况类似,不画。

直到这里,我们把 0 ~ 14 的状态都填好了,接下来考虑最终极的, 15(1111,满行)状态的情况。

4、 i - 1 行缺 连2位 的情况(0011 = 3, 1001 = 9, 1100 = 12),可以通过放置2个竖的积木和1个横的积木达到完美,例如
这里写图片描述

其他2种情况不再赘画。

5.、i - 1 行如果已经是满的,我们直接横放2个积木,i 行也满,这种不用画了吧。

#include <stdio.h>#define maxx 10000#define maxw 1000int f[maxx+9][1<<4] ; // int main () {    int L,n ;    f[1][0] = f[1][3] = f[1][6] = f[1][12] = f[1][15] = 1 ;    for ( int i = 2 ; i <= maxw ; ++i ) {        // 竖放   1        for ( int j = 0 ; j <= 15 ; ++j ) {            f[i][j] = f[i-1][15-j] ;        }        // 横放       2        f[i][3] += f[i-1][15] ;        f[i][6] += f[i-1][15] ;        f[i][12] += f[i-1][15] ;        // 横加竖      3        f[i][7] += f[i][4] + f[i][1] ;        f[i][14] += f[i][8] + f[i][2] ;        // 混合型      4   ( 2竖1横 )         f[i][15] += f[i-1][3] + f[i-1][6] + f[i-1][12] ;        // 混合型      5   ( 2横 )         f[i][15] += f[i-1][15] ;    }    scanf ( "%d" , &n ) ;    for ( int cas = 1 ; cas <= n ; ++cas ) {        scanf ( "%d" , &L ) ;        printf ( "%d %d\n" , cas , f[L][15] ) ;    }}          

转载来自 http://blog.csdn.net/linhan8/article/details/7760933

0 0
原创粉丝点击