【HDU1693】Eat the Trees(插头DP)

题目大意:找若干个环,布满地图所有白格,求方案数。HDU1693

题解:dp[I][j][s]表示I,j轮廓线时,轮廓线上的插头状态为s(01状态压缩),的方案数。转移:
①当前格为白格:
情况1
不能增加新插头。
情况2
任选一个蓝插头
情况3
必须选下面两个蓝插头。
②当前格为黑格
1.有插头通往这里:不可能,方案数为0;
2.没有插头通往这里:直接转移上一次方案数。

代码:

#include<cstdio>
#include<cstring>
#define MAXN 13
#define MAXS 5000
bool mat[MAXN][MAXN];
long long dp[MAXN][MAXN][MAXS];
int main()
{
	int T,x,n,m;
	scanf("%d",&T);
	for(int test=1;test<=T;test++)
	{
		scanf("%d%d",&n,&m);
		memset(mat,0,sizeof mat);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
				scanf("%d",&x);
				mat[i][j]=(bool)x;
			}
		memset(dp,0,sizeof dp);
		dp[0][m][0]=1;
		for(int i=1;i<=n;i++)
		{
			for(int s=0;s<(1<<m);s++)
				dp[i][0][s<<1]=dp[i-1][m][s];
			for(int j=1;j<=m;j++)
				for(int s=0;s<(1<<(m+1));s++)
				{
					int p=1<<j,q=p>>1;
					bool x=s&p,y=s&q;
					if(mat[i][j])
					{
						dp[i][j][s]=dp[i][j-1][s^p^q];
						if(x!=y)
							dp[i][j][s]+=dp[i][j-1][s];
					}
					else
					{
						if(!x&&!y)
							dp[i][j][s]=dp[i][j-1][s];
						else
							dp[i][j][s]=0;
					}
				}
		}
		printf("Case %d: There are %lld ways to eat the trees.\n",test,dp[n][m][0]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CaptainHarryChen

随便

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值