HDOJ 1693 插头dp

本文介绍了一种使用状态压缩动态规划解决基于连通性的路径寻找问题的方法。该算法适用于处理网格中障碍物的问题,通过状态压缩减少内存消耗,并通过动态规划找到从起点到终点的可行路径数量。

百度一下:基于连通性状态压缩的动态规划问题


#include <iostream>
using namespace std;

const int maxn = 12;
__int64 dp[maxn][maxn][1<<maxn];
int mp[12][12];

int main(){
	int T;
	scanf("%d",&T);
	for(int Case=1;Case<=T;Case++){
		int i,j,k,m,n;
		scanf("%d%d",&m,&n);
		for(i=1;i<=m;i++)
			for(j=1;j<=n;j++)
				scanf("%d",&mp[i][j]);
		memset(dp,0,sizeof(dp));
		dp[0][n][0]=1;
		for(i=1;i<=m;i++){
			for(j=0;j<(1<<n);j++)
				dp[i][0][j<<1]=dp[i-1][n][j];
			//把状态下拉一行
			//[i,n]的状态x和[i+1,0]的状态x是对应相同的
			//所以也避免了初始化的麻烦
			//上一行最右边的边格一定不与轮廓线重合
			//下一行最左边的边格一定不与轮廓线重合
			for(j=1;j<=n;j++){
				for(k=0;k<(1<<(n+1));k++){
					int p = 1<<j;
					//(i,j)轮廓段上插头
					int q = p>>1;
					//(i,j)轮廓段左插头
					bool x = p & k;
					bool y = q & k;
					if (mp[i][j]){//可以走
						dp[i][j][k]=dp[i][j-1][k^p^q];
						//必然有一个通路连接上一个格子的通路
						if (x!=y)
							dp[i][j][k]+=dp[i][j-1][k];
							//有一处新覆盖则有另外的一种情况
					}
					else{//为障碍格子
						if (x+y==0)//道路与轮廓线不相交
							dp[i][j][k]=dp[i][j-1][k];//和前面一个格子的状态数相同
						else
							dp[i][j][k]=0;
							//不合法,障碍格子不可能与轮廓线相交
					}
				}
			}
		}
		printf("Case %d: There are %I64d ways to eat the trees.\n",Case,dp[m][n][0]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值