//poj 1038 Bugs Integrated, Inc.(动态规划状态压缩)
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int N=160;
const int M=15;
int sta[12]={0,1,3,9,27,81,243,729,2187,6561,19683,59049};
int dp[2][60000];
int map[N][M];
int pre[N],now[N];//pre[]是前一个已经算出它个数的状态
int n,m,k;
int Max(int a,int b)//返回最大值
{
if(a>b)
{
return a;
}
return b;
}
int stagetsum(int s[])//三进制转十进制
{
int sum=0;
for(int i=1;i<=m;i++)
{
sum+=sta[i]*s[i];
}
return sum;
}
void sumgetsta(int sum,int s[])//十进制转三进制
{
for(int i=1;i<=m;i++)
{
s[i]=sum%3;
sum=sum/3;
}
}
void dfs(int i,int j,int last,int key)//深搜每一层
{
int k;
dp[i%2][key]=Max(dp[i%2][key],last);
if(j>=m)
{
return ;
}
if(!pre[j]&&!pre[j+1]&&!now[j]&&!now[j+1])
{
now[j]=now[j+1]=2;
k=stagetsum(now);
dfs(i,j+2,last+1,k);
now[j]=now[j+1]=0;
}
if(j<m-1&&!now[j]&&!now[j+1]&&!now[j+2]&&pre[j]!=2&&pre[j+1]!=2&&pre[j+2]!=2)
{
now[j]=now[j+1]=now[j+2]=2;
k=stagetsum(now);
dfs(i,j+3,last+1,k);
now[j]=now[j+1]=now[j+2]=0;
}
dfs(i,j+1,last,key);
return ;
}
void DP()//动态压缩
{
for(int i=1;i<=m;i++)
{
pre[i]=map[1][i]+1;
}
int d=stagetsum(pre);
dp[1][d]=0;
for(int i=2;i<=n;i++)
{
for(int j=0;j<sta[m+1];j++)
{
dp[i%2][j]=-1;
}
for(int j=0;j<sta[m+1];j++)
{
if(dp[(i+1)%2][j]==-1) continue;
sumgetsta(j,pre);
for(int z=1;z<=m;z++)
{
if(map[i][z])
{
now[z]=2;
}
else
{
now[z]=Max(pre[z]-1,0);
}
}
d=stagetsum(now);
dfs(i,1,dp[(i+1)%2][j],d);
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&k);
memset(map,0,sizeof(map));
for(int i=0;i<sta[m+1];i++)
{
dp[1][i]=-1;
}
for(int i=0;i<k;i++)
{
int a,b;
scanf("%d%d",&a,&b);
map[a][b]=1;
}
DP();
int ans=0;
for(int i=0;i<sta[m+1];i++)
{
ans=Max(ans,dp[n%2][i]);
}
printf("%d\n",ans);
}
return 0;
}
poj 1038 Bugs Integrated, Inc.(动态规划状态压缩)
最新推荐文章于 2021-02-03 17:16:04 发布