插头DP入门题,细节很多,我用的BFS(好像我就只会BFS…)
AC code:
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int N=20;
int T,I,n,m;
int bt[N];
int ok[N][N];
struct State{
int i,j,S;
State(int i,int j,int S):i(i),j(j),S(S) {}
};
void read(){
memset(ok,0,sizeof(ok));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
scanf("%d",&ok[i][j]);
}
for(int i=1;i<=m+1;i++) bt[i]=(m+1-i)<<1;
}
int get(int S,int k){
return ((S&(1<<(bt[k])))+(S&(1<<(bt[k]+1))))>>bt[k];
}
int modify(int S,int k,int s){
return S^(get(S,k)<<bt[k])^(s<<bt[k]);
}
void DP(){
queue<State> Q;
map<int,ll> f[N][N];
Q.push(State(0,m,0));
f[0][m][0]=1;
while(!Q.empty()){
State x=Q.front();
Q.pop();
int i=x.i,j=x.j+1,S=x.S,SS;
if(j==m+1){
i++;j=1;
S>>=2;
if(i==n+1) break;
}
int c1=get(S,j),c2=get(S,j+1);
if(!ok[i][j]){
if(!f[i][j][S]) Q.push(State(i,j,S));
f[i][j][S]+=f[x.i][x.j][x.S];
}
else if((!c1)&&(!c2)&&ok[i+1][j]&&ok[i][j+1]){
SS=modify(modify(S,j,1),j+1,2);
if(!f[i][j][SS]) Q.push(State(i,j,SS));
f[i][j][SS]+=f[x.i][x.j][x.S];
}
else if((!c1)&&c2){
if(ok[i+1][j]){
SS=modify(modify(S,j,c2),j+1,c1);
if(!f[i][j][SS]) Q.push(State(i,j,SS));
f[i][j][SS]+=f[x.i][x.j][x.S];
}
if(ok[i][j+1]){
if(!f[i][j][S]) Q.push(State(i,j,S));
f[i][j][S]+=f[x.i][x.j][x.S];
}
}
else if(c1&&(!c2)){
if(ok[i+1][j]){
if(!f[i][j][S]) Q.push(State(i,j,S));
f[i][j][S]+=f[x.i][x.j][x.S];
}
if(ok[i][j+1]){
SS=modify(modify(S,j,c2),j+1,c1);
if(!f[i][j][SS]) Q.push(State(i,j,SS));
f[i][j][SS]+=f[x.i][x.j][x.S];
}
}
else if(c1&&c2){
SS=modify(modify(S,j,0),j+1,0);
if(c1==1&&c2==1){
for(int k=j+2;k<=m+1;k++){
if(get(SS,k)==2){
SS=modify(SS,k,1);
break;
}
}
}
else if(c1==2&&c2==2){
for(int k=j-1;k>=1;k--){
if(get(SS,k)==1){
SS=modify(SS,k,2);
break;
}
}
}
if(!f[i][j][SS]) Q.push(State(i,j,SS));
f[i][j][SS]+=f[x.i][x.j][x.S];
}
}
printf("Case %d: There are %lld ways to eat the trees.\n",I,f[n][m][0]);
}
int main(){
scanf("%d",&T);
for(I=1;I<=T;I++){
read();
DP();
}
return 0;
}