POJ 2411 Mondriaan's Dream

本文介绍了一个状态压缩动态规划(DP)的问题解决思路及代码实现。通过一个具体的例子讲解了如何利用状态压缩技术来减少状态数量,并给出了清晰的代码示例。适用于初学者理解和实践状态压缩DP。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一个状态压缩dp

借鉴博客:http://blog.sina.com.cn/s/blog_64018c250100v1nb.html

(写得很好理解 值得看)

主要是弄清一个位置可能有几个状态   

这题 就两个   1 表示放置  0表示不放置(个人理解:1为矩阵在此行结束,0表示矩阵不在此行结束)

代码:

#include<iostream>
using namespace std;//状态压缩dp
#define N 2500
__int64 dp[15][N],h,w;  //dp[i][s]表示 第i-1行放满后,第i行的状态为s的种类
void init(int d,int s)    //初始时第1行只有两个状态  水平放置 不放 
{
	if(d==w)
	{
		dp[0][s]++;
		return ;
	}
	if(d+2<=w)init(d+2,s<<2|3);
	if(d+1<=w)init(d+1,s<<1);	
}
void dfs(int r,int d,int s1,int s2) //s1表示第r行第d列的状态  s2 表示第r-1行第d列的状态
{
	if(d==w)
	{
		dp[r][s1]+=dp[r-1][s2];   //dp[i][s1]=sigma(dp[i-1][s2])
		return ;
	}
	if(d+1<=w)
	{
		dfs(r,d+1,s1<<1|1,s2<<1);  // 竖放一个,在该行结束
		dfs(r,d+1,s1<<1,s2<<1|1);   //不放置   下行结束
	}
	if(d+2<=w)
		dfs(r,d+2,s1<<2|3,s2<<2|3); //水平放置
}
int main()
{
	int i;
	while(scanf("%I64d%I64d",&h,&w),h&&w)
	{
		if(h==0||w==0||h*w%2)
		{
			printf("0\n");
			continue;
		}
		if(h==1||w==1)
		{
			printf("1\n");
			continue;
		}
		memset(dp,0,sizeof(dp));
		init(0,0);
		for(i=1;i<h;i++)
			dfs(i,0,0,0);
		printf("%I64d\n",dp[h-1][(1<<w)-1]);
	}
	return 0;

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值