hdu_4529_郑厂长系列故事——N骑士问题(状压DP)

37 篇文章 0 订阅

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4529

题意:中文,不解释

题解:状压DP,dp[i][j][k][s]表示第i行当前用了j个骑士,i-1行的压缩状态为k,i行的压缩状态为j,然后用滚动数组优化了一下,注意如果不预处理不可存放位置会超时

#include<cstdio>
#include<cstring>
#define N (1<<8)
#define FFC(i,a,b) for(int i=a;i<=b;++i)
	
int T,n,dp[2][23][N][N],g[N],num[N],f1[N][N],f2[N][N],cur,ans;

void init(){//预处理不可放的位置,和每一个压缩状态的骑士数目
	FFC(i,0,N-1){
		FFC(j,0,7)if(i&(1<<j))num[i]++;
		FFC(j,0,N-1){
			if(((i>>2)&j)||((j>>2)&i))f1[i][j]=1;
			if(((i>>1)&j)||((j>>1)&i))f2[i][j]=1;
		}
	}
}
int fuck(){
	memset(dp,0,sizeof(dp));
	cur=0,ans=0,dp[0][0][0][0]=1;
	FFC(i,0,7){
		FFC(j,0,n)FFC(p,0,N-1)FFC(q,0,N-1){
			if (dp[cur][j][p][q]==0)continue;
			FFC(z,0,N-1)
				if (((z&g[i+1])!=z)||num[z]+j>n||(i>=1&&f1[q][z])||(i>=2&&f2[p][z]))continue;
				else dp[cur^1][num[z]+j][q][z]+=dp[cur][j][p][q];
		}
		memset(dp[cur],0,sizeof(dp[cur])),cur^=1;
	}
	FFC(i,0,N-1)FFC(j,0,N-1)ans+=dp[cur][n][i][j];
	return ans;
}

int main() {
	init();char str[N];
	scanf("%d",&T);
	while (T--){
		scanf("%d",&n);	
		memset(g,0,sizeof(g));
		FFC(i,1,8){
			scanf("%s",str);
			FFC(j,0,7){
				g[i]<<=1;
				if(str[j]=='.')g[i]|=1;
			}
		}
		printf("%d\n",fuck());
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值