【题目分析】

经典题目,插头DP。

switch 套 switch 代码瞬间清爽了。

【代码】

#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 maxn 400005
const int md=20110520;
int dp[2][maxn],a[101][101],n,m,fac[15],tot,b[15];
char s[105];
void print(int x){F(i,0,m) printf("%d",(x%fac[i+1])/fac[i]);}
int main()
{
scanf("%d%d",&n,&m);
F(i,0,n-1){scanf("%s",s);F(j,0,m-1)a[i][j]=s[j]=='*'?1:0;}
if (m>n){F(i,0,m-1)F(j,i+1,m-1)swap(a[i][j],a[j][i]);swap(m,n);}
// F(i,0,n-1){F(j,0,m-1)printf("%d ",a[i][j]);printf("\n");}
fac[0]=1;F(i,1,13)fac[i]=fac[i-1]*3;tot=fac[m+1]-1;
int now=1,pre=0;
memset(dp[now],0,sizeof dp[now]);
dp[now][0]=1;
F(i,0,n-1) F(j,0,m-1)
{ if (a[i][j])
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("now is "); print(s); printf(" \n");
int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
if (!tmp1&&!tmp2)
{
(dp[now][s]+=dp[pre][s])%=md;
// printf(" to "); print(s); printf("\n");
}
}
}
else
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("now is "); print(s); printf(" \n");
int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
switch(tmp1)
{
case 0:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]+2*fac[j+1]); printf("\n");
(dp[now][tmp+2*fac[j]+2*fac[j+1]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j]); printf("\n");
(dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j+1]); printf("\n");
(dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
break;
case 1:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+fac[j]); printf("\n");
(dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+2*fac[j+1]); printf("\n");
(dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
break;
case 2:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
break;
}
break;
case 1:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j+1]); printf("\n");
(dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
break;
case 1:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
break;
case 2:
break;
}
break;
case 2:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
break;
case 1:
break;
case 2:
break;
}
break;
}
}
}
if (j==m-1)
{
// printf("On The last of road\n");
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("End with "); print(s);
int tmp=s,tmp1=(s%fac[m+1])/fac[m];
if (tmp1) {continue;}
tmp*=3;
// printf(" can become "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
}
}
}
printf("%d\n",dp[now][0]);
}

  

04-28 02:23