首页 > 代码库 > ZOJ 2994 && HDU 1992 Tiling a Grid With Dominoes (状压DP)

ZOJ 2994 && HDU 1992 Tiling a Grid With Dominoes (状压DP)

题目链接:HDU 1992 Tiling a Grid With Dominoes

题意:一个4*N的矩形,用1*2的小矩形铺满的方法数是多少。

思路:4*N。只有4行想到状压,dp[i][j]表示前i行状态j的方法数,影响当前行的只有上一行!0成对出现表示横着放,1表示竖着放,所以第一行的状态0.3.9.12.15五种,并且只要上一行是0状态。当前行的状态就为0.3.9.12.15五种可能。还有当前行s1和上一行s2匹配仅当s1==0 || s1==(s2取反),特别注意上一行状态是0110(6)时只有1001(9)和其匹配。答案不超int。n最大22~



AC代码:


#include <stdio.h>
#include <string.h>
#include <vector>
int dp[30][20]; // 前i行状态j的方法数

bool ok(int pres,int nxts){
	int tmp;
	tmp=pres^15;
	//注意
	if(pres==6){
		if(nxts==9)
			return true;
		return false;
	}
	if(nxts==0 || nxts==tmp)
		return true;
	return false;
}
int main()
{
	int cas=1;
	int t,n,i,j,k;
	scanf("%d",&t);
	while(t--){
		memset(dp,0,sizeof dp);
		scanf("%d",&n);

		for(i=0;i<n;i++){
			if(i==0){
				for(j=0;j<16;j++){
					if(j==0 || j==3 || j==9 || j==12 || j==15){
						dp[i][j]=1;
					}
				}
			}else{
				//j上一行状态,k这一行状态
				for(j=0;j<16;j++){
					if(!dp[i-1][j])
						continue;
					if(j==0){
						for(k=0;k<16;k++){
							if(k==0 || k==3 || k==9 || k==12 || k==15){
								//printf("%d -> %d (%d)\n",j,k,dp[i-1][j]);
								dp[i][k]+=dp[i-1][j];
							}
						}
					}else{
						for(k=0;k<16;k++){
							if(ok(j,k)){
								//printf("%d -> %d (%d)\n",j,k,dp[i-1][j]);
								dp[i][k]+=dp[i-1][j];
							}
						}
					}
				}
			}
		}
		printf("%d %d\n",cas++,dp[n-1][0]);
	}
	return 0;
}


ZOJ 2994 && HDU 1992 Tiling a Grid With Dominoes (状压DP)