POJ 1038 Bugs Integrated, Inc. ——状压DP

本文介绍了一种结合状态压缩动态规划(状压DP)与深度优先搜索(DFS)算法来解决特定问题的方法。该方法通过状态压缩减少内存消耗,并利用DFS进行状态转移,适用于处理涉及多个方块的状态变化问题。代码示例展示了如何通过递归DFS遍历所有可能的状态并更新动态规划表。

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

状压上面有几个方块,然后DFS转移。

复杂度貌似很高$3_{}^{20}*n$

反正过了

#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair
#define mask(i) ((mask%pow[i+1])/pow[i])
#define a(i) (a[x][i])
int dp[2][500005],pow[20],n,m,k;
int a[205][20],t,now,pre;
void print(int mask)
{F(i,0,m-1)printf("%d",(mask%pow[i+1])/pow[i]);}
void dfs(int x,int y,int mask,int val)
{
	if (y>=m){dp[pre][mask]=max(val,dp[pre][mask]);return;}
	if (y+2<m&&!a(y)&&!a(y+1)&&!a(y+2)&&mask(y)==mask(y+1)&&mask(y+1)==mask(y+2))
	{
		if (mask(y)==1)
		{
			mask-=pow[y]+pow[y+1]+pow[y+2];
			dfs(x,y+3,mask,val+1);
			mask+=pow[y]+pow[y+1]+pow[y+2];
		}
		else
		{
			mask+=pow[y]+pow[y+1]+pow[y+2];
			dfs(x,y+3,mask,val);
			mask-=pow[y]+pow[y+1]+pow[y+2];
		}
	}
	if (y+1<m&&!a(y)&&!a(y+1)&&mask(y)==mask(y+1))
	{
		if (mask(y)<2)
		{
			mask+=pow[y]+pow[y+1];
			dfs(x,y+2,mask,val);
			mask-=pow[y]+pow[y+1];
		}
		else
		{
			mask-=2*pow[y]+2*pow[y+1];
			dfs(x,y+2,mask,val+1);
			mask+=2*pow[y]+2*pow[y+1];
		}
	}
	if (!mask(y))
	{
		dfs(x,y+1,mask,val);
	}
}
int main()
{
	scanf("%d",&t);
	pow[0]=1;
	F(i,1,14)pow[i]=pow[i-1]*3;
	while (t--)
	{
		memset(a,0,sizeof a);
		scanf("%d%d%d",&n,&m,&k);
		F(i,1,k)
		{
			int x,y;scanf("%d%d",&x,&y);
			x--; y--;
			a[x][y]=1;
		}
		F(i,0,m-1) a[n][i]=1;
		now=1;pre=0;
		memset(dp[pre],-1,sizeof dp[pre]);
		dp[pre][0]=0;
		F(i,0,n)
		{
			now^=1; pre^=1;
			memset(dp[pre],-1,sizeof dp[pre]); 
			F(j,0,pow[m]-1) if (~dp[now][j])
			{
				dfs(i,0,j,dp[now][j]);
			}
		}
		printf("%d\n",dp[pre][0]);
	}
}

  

转载于:https://www.cnblogs.com/SfailSth/p/6647581.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值