废话少说,代码说话 #include <stdio.h> static double cnt[12][1<<11]; static int trans[16384][2]; int rows, cols, ntrans; /* there are ((sqrt(2)+1)^c - (sqrt(2)-1)^c) * (sqrt(2)+2) / 4 transitions * which is the solution to T_{c} = 2 * T_{c-1} + T_{c-2} */ void backtrack (int n, int from, int to) // 这个函数产生row与row之间的递推数组 { if (n > cols) return; if (n == cols) { trans[ntrans][0] = from; trans[ntrans][1] = to; ++ntrans; return; } backtrack (n+2, from<<2, to<<2); // from层跟to层分别向左移动两位,这样from层两个位置已经铺满,导致to层连着铺两块 backtrack (n+1, from<<1, (to<<1)|1); // from层跟to层分别向左移动一位,这样from层一个位置已经铺满,导致to层不能铺 backtrack (n+1, (from<<1)|1, to<<1); // from层跟to层分别向左移动一位,这样from层这个位置是空的,to层可以利用这个位置竖着铺 } int main () { freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); int r,t; while (scanf("%d%d",&rows,&cols) && rows!=0 ) { if (rows < cols) { t = rows; rows = cols ; cols = t; } /* calculate map of possible transitions by linear backtracking */ ntrans = 0; backtrack (0, 0, 0); for (r=0 ; r<=rows ; r++) for (t=0 ; t<(1<<cols) ; t++) cnt[r][t] = 0; cnt[0][0] = 1; for (r=0 ; r<rows ; r++) /* the r topmost rows are already filled */ // 利用递推数组直接往下加 for (t=0 ; t<ntrans ; t++) /* perform all transitions */ cnt[r+1][trans[t][1]] += cnt[r][trans[t][0]]; printf ("%.0f/n", cnt[rows][0]); } return 0; }