pku 2411 dp + 状态压缩

 

#include <iostream>
using namespace std;

//1:竖放,影响下层
//0:横放 或 被上层竖放的占
__int64 dp[12][2050];
int h,w,i,j,stateNum;

void dfs(int pos, int state) //pos是每层从右往左数的位置
{
	if(pos == w+1)
	{//已到一层末位 则该层的state要加上 上一层的j的个数
		dp[i+1][state] += dp[i][j];
		return;
	}
	else
	{
		if ((j >> (pos-1) & 1) == 1)
		{//若上层pos位上为1 即被上层影响 上层pos位有竖放 
			dfs(pos+1, state); //则该层只能是0 state不变 往左放下个位置
		}
		else
		{//若上层pos位上为0 
			if (pos+1 <= w && (j >> pos & 1) == 0)
			{//横放 pos位左面还有至少一个位置 且该位置未被上层影响
				dfs(pos+2, state);
			}
			dfs(pos+1, state | (1 << (pos-1))); //竖放 state在pos位上变为1
		}
	}
}
int main()
{
	while (scanf("%d %d", &h, &w) != EOF)
	{
		if (h*w % 2)
		{
			printf("0\n");
			continue;
		}
		else if(h == 0 && w == 0)
		{
			break;
		}
		
		memset(dp, 0, sizeof(dp));
		dp[0][0] = 1; //第0行 不存在 假设只有一个状态 即不存在竖放
		stateNum = 1 << w;

		for (i = 0; i <= h-1; ++i)
		{
			for (j = 0; j < stateNum; ++j)
			{
				if (dp[i][j])
				{
					dfs(1,0);
				}
			}
		}
		printf("%I64d\n", dp[h][0]);
	}
	return 0;
}

 

posted on 2009-07-24 16:06  ZAFU_VA  阅读(704)  评论(2)    收藏  举报

导航