poj 1185 状态压缩

状态压缩经典题目

令res[i][j][k]表示第i行状态为第j个状态时,第i-1行的状态为第k个状态时最多能摆放的个数,令state[i][j]表示第i行的第j个状态,kk[i][j]表示第i行第j个状态所放的个数,len[i]表示第i行的可能的状态数。

则:

res[i][j][k]=max(res[i][j][k],res[i-1][k][l]+kk[i][j]);(0<=l<len[i-2])

结果就是:在res[n][j][k]中找一个最大的。

状态压缩经典题目
令res[i][j][k]表示第i行状态为第j个状态时,第i-1行的状态为第k个状态时最多能摆放的个数,令state[i][j]表示第i行的第j个状态,kk[i][j]表示第i行第j个状态所放的个数,len[i]表示第i行的可能的状态数。
则:
res[i][j][k]=max(res[i][j][k],res[i-1][k][l]+kk[i][j]);(0<=l<len[i-2])
结果就是:在res[n][j][k]中找一个最大的。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int res[110][65][65],state[110][65],kk[110][65],len[110],m,n;
char map[110][12];
int init(int i,int j,int s,int inum,int b)//初始化构造state[][]和kk[][]
{
if(j>=m)
{
state[i][len[i]]=s>>(j-m);
kk[i][len[i]]=inum;
len[i]++;
return 0;
}
if(b==1)
{
if(map[i][j+3]=='P') init(i,j+3,(s<<3)+1,inum+1,1);
init(i,j+3,s<<3,inum,0);
}
if(b==0)
{
if(map[i][j+1]=='P') init(i,j+1,(s<<1)+1,inum+1,1);
init(i,j+1,s<<1,inum,0);
}
return 0;
}
int Max(int a,int b)
{
return a > b ? a : b;
}
int work(int n)
{
int i,j,k,l,max=0;
for(i=2;i<=n;i++)
{
for(j=0;j<len[i];j++)
{
for(k=0;k<len[i-1];k++)
if((state[i][j] & state[i-1][k])==0)
{
for(l=0;l<len[i-2];l++)
if((state[i-2][l] & state[i][j])==0 && (state[i-2][l] & state[i-1][k])==0)
{
res[i][j][k]=Max(res[i][j][k],res[i-1][k][l]+kk[i][j]);
}
}
}
}
for(i=0;i<len[n];i++)
for(j=0;j<len[n-1];j++)
if(max < res[n][i][j]) max=res[n][i][j];
return max;
}
int main()
{
int i,j;
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
for(i=1;i<=n;i++) scanf("%s",map[i]+1);

memset(len,0,sizeof(len));
memset(res,0,sizeof(res));
for(i=1;i<=n;i++) init(i,0,0,0,0);
len[0]=1;

for(i=0;i<len[1];i++) res[1][i][0]=kk[1][i];
printf("%d\n",work(n));

}
return 0;
}



你可能感兴趣的:(poj)