同样是轮廓线
我们有一下 种情况
1.这个位置左侧有插头,且右侧不是障碍
将其修改为
2.这个位置上面有插头,且下侧不是障碍
将其修改为
3.这个位置上、左都有插头,且当前节点不是障碍
将其修改为
4.如果这个位置上、左都没有插头
将其修改为
5.如果这个位置有障碍
当上和左都是0的时候,将其直接转移即可
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=13;
int t;
int n,m,ma[maxn][maxn];
long long f[maxn][maxn][1<<14];
int getbit(int s,int x)
{
return (s>>x-1)&1;
}
int changebit(int s,int pos,int x)
{
if(getbit(s,pos)!=x)
return s^(1<<pos-1);
return s;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&t);
for(int z=1;z<=t;z++)
{
scanf("%d%d",&n,&m);
memset(ma,0,sizeof(ma));
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&ma[i][j]);
f[1][1][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int s=0;s<(1<<m+1);s++)
{
int up=getbit(s,j+1);
int left=getbit(s,j);
if(!f[i][j][s]) continue;
//printf("f[%d][%d][%d]=%lld\n",i,j,s,f[i][j][s]);
if(!ma[i][j])
{
if(!up && !left)
f[i][j+1][s]=f[i][j][s];
continue;
}
if(up && left)
{
int k=changebit(s,j+1,0);
k=changebit(k,j,0);
f[i][j+1][k]+=f[i][j][s];
continue;
}
if(up || left)
{
int k=changebit(s,j+1,0);
k=changebit(k,j,0);
if(ma[i][j+1])
{
int t=changebit(k,j+1,1);
f[i][j+1][t]+=f[i][j][s];
}
if(ma[i+1][j])
{
int t=changebit(k,j,1);
f[i][j+1][t]+=f[i][j][s];
}
continue;
}
if(ma[i][j+1] && ma[i+1][j])
{
int t=changebit(s,j+1,1);
t=changebit(t,j,1);
f[i][j+1][t]+=f[i][j][s];
}
}
}
for(int s=0;s<(1<<m+1);s++)
if(f[i][m+1][s]) f[i+1][1][s<<1]+=f[i][m+1][s];
}
printf("Case %d: There are %lld ways to eat the trees.\n",z,f[n+1][1][0]);
}
return 0;
}