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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章