用00表示2*1的长方形,11表示1*2的长方形,
则每一行的每一个状态对下一行的状态有要求,gastStateLimit[][i]表示某行第i种状态对下一行的各种要求。
最后一行没有“凸出”,也就是对“下一行”没有要求,因此也就是统计最后一行各个状态对下一行没有要求的总数。
/*Mondriaan's Dream TiHeighte LiHeightit: 3000MS Memory LiHeightit: 65536K Total Submissions: 5413 Accepted: 3092 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series' (where he had to use his toilet paper to draw on, for all of his paper was filled with squares and rectangles), he dreamt of filling a large rectangle with small rectangles of width 2 and height 1 in varying ways. Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose diHeightensions were integer values, as well. Help hiHeight, so that his dream won't turn into a nightmare! Input The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0. Otherwise, 1<=h,w<=11. Output For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 tiHeightes 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple tiHeightes. 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 Source Ulm Local 2000 */ #include <stdio.h> #include "string.h" #define MAX_HEIGHT_WIDTH_SIZE 11 #define MAX_STATE_NUM 150 typedef struct _POSSIBLE_STATE_ST_ { int aiState[MAX_STATE_NUM]; }POSSIBLE_STATE_ST; typedef struct _STATE_LIMIT_ST_ { int iLimitNum; struct { __int64 iReachedNum; int iRequstForNextLine;/*对下一行的的要求*/ }astLimit[465]; }STATE_LIMIT_ST; POSSIBLE_STATE_ST gstPossibleRowState; STATE_LIMIT_ST gastStateLimit[2][MAX_STATE_NUM]; int MondriaansDreammain(void) { int iHeight; int iWidth; int iLoop; int iLoopLine; int iState; int iStateNum; int iLoopState; int iLoopPreLineState; int iLoopLimit; int iNumOf1; __int64 iResult = 0; int iNextLimit = 0; int iCurLimit = 0; int iRequstForNextLine; int aiLimitHash[2048]; int aiStateNum[MAX_HEIGHT_WIDTH_SIZE+1]; /*init possible state*/ iLoopState = 0; iStateNum = 0; for(iLoop = 1; iLoop <= MAX_HEIGHT_WIDTH_SIZE; iLoop++ ) { for (; iLoopState < 1<<iLoop; iLoopState++) { iNumOf1 = 0; iState = iLoopState; /*连续出现奇数个1的状态不可取*/ while (iState) { if (iState&0x01) { iNumOf1 ++; } else { if (iNumOf1%2) { break; } iNumOf1 = 0; } iState >>= 1; } if (iState||iNumOf1%2) {/*invalid state*/ continue; } gstPossibleRowState.aiState[iStateNum] = iLoopState; iStateNum++; } aiStateNum[iLoop] = iStateNum; } while (1) { scanf("%d %d",&iHeight,&iWidth); if (0 == iHeight && 0 == iWidth) { break; } if ((iHeight*iWidth%2) || 0 == iHeight*iWidth ) { printf("0/n"); continue; } if (1 == iHeight) { printf("1/n"); continue; } iStateNum = (1<<iWidth); /*1st line*/ iNextLimit = 0; for (iLoopState = 0; iLoopState < aiStateNum[iWidth]; iLoopState++) { gastStateLimit[iNextLimit][iLoopState].iLimitNum = 1; gastStateLimit[iNextLimit][iLoopState].astLimit[1].iReachedNum = 1; gastStateLimit[iNextLimit][iLoopState].astLimit[1].iRequstForNextLine = ((~gstPossibleRowState.aiState[iLoopState])&(iStateNum-1)); } iCurLimit = iNextLimit; iNextLimit = (iNextLimit+1)%2; /*2nd~nth line*/ for (iLoopLine = 1; iLoopLine < iHeight; iLoopLine++) { for (iLoopState = 0; iLoopState < aiStateNum[iWidth]; iLoopState++) { memset(aiLimitHash,0,iStateNum*sizeof(int)); gastStateLimit[iNextLimit][iLoopState].iLimitNum = 0; /*与前1行不矛盾*/ for (iLoopPreLineState = 0; iLoopPreLineState < aiStateNum[iWidth]; iLoopPreLineState++) { for (iLoopLimit = 1; iLoopLimit <= gastStateLimit[iCurLimit][iLoopPreLineState].iLimitNum;iLoopLimit++) { if (0 == (gastStateLimit[iCurLimit][iLoopPreLineState].astLimit[iLoopLimit].iRequstForNextLine&gstPossibleRowState.aiState[iLoopState])) { iRequstForNextLine = (((~gstPossibleRowState.aiState[iLoopState])&(iStateNum-1))^gastStateLimit[iCurLimit][iLoopPreLineState].astLimit[iLoopLimit].iRequstForNextLine); if(aiLimitHash[iRequstForNextLine]) { gastStateLimit[iNextLimit][iLoopState].astLimit[aiLimitHash[iRequstForNextLine]].iReachedNum += gastStateLimit[iCurLimit][iLoopPreLineState].astLimit[iLoopLimit].iReachedNum; } else { gastStateLimit[iNextLimit][iLoopState].iLimitNum++; gastStateLimit[iNextLimit][iLoopState].astLimit[gastStateLimit[iNextLimit][iLoopState].iLimitNum].iReachedNum = gastStateLimit[iCurLimit][iLoopPreLineState].astLimit[iLoopLimit].iReachedNum; gastStateLimit[iNextLimit][iLoopState].astLimit[gastStateLimit[iNextLimit][iLoopState].iLimitNum].iRequstForNextLine = iRequstForNextLine; aiLimitHash[iRequstForNextLine] = gastStateLimit[iNextLimit][iLoopState].iLimitNum; } } } } } iCurLimit = iNextLimit; iNextLimit = (iNextLimit+1)%2; } /*求最后一行的和即结果*/ iResult = 0; for (iLoopState = 0; iLoopState < aiStateNum[iWidth]; iLoopState++) { for (iLoopLimit = 1; iLoopLimit <= gastStateLimit[iCurLimit][iLoopState].iLimitNum;iLoopLimit++) { if (0 == gastStateLimit[iCurLimit][iLoopState].astLimit[iLoopLimit].iRequstForNextLine) { iResult += gastStateLimit[iCurLimit][iLoopState].astLimit[iLoopLimit].iReachedNum; break; } } } printf("%I64d/n",iResult); } return 0; }