int dp[10][10][19690]; //传说中的三进制
int bit[]={1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683};
char ok[13][13];
int st[1000][10], go[19900], p[900][10], slack[10];
int k, num, tot;
int main()
{
int n, m;
for(int i=0, j; i<=bit[9]; i++)
{
k = num = 0, j = i, ++tot;
for (; j>0; j/=3)
{
int h = j % 3;
st[tot][k++] = h;
if (h == 1) ++num;
if (h == 2) --num;
if (num < 0) break;
}
if (num != 0) --tot;
else
{
go[st[tot][9] = i] = tot;
for (k = num = 0; k <= 8; ++k)
if (st[tot][k] == 2)
p[tot][k] = slack[num], p[tot][slack[num--]] = k;
else if (st[tot][k] == 1) slack[++num] = k;
}
}
while(scanf("%d%d", &n, &m), n)
{
memset(dp, 0, sizeof(dp));
dp[1][0][1] = 1;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j) scanf("%c", &ok[i][j]);
scanf("\n");
}
if (n == 1)
{
int i;
for (i = 1; i <= m; ++i)
if (ok[i][1] == '#') break;
printf("%d\n", i > m);
continue;
}
for(int i=1; i<=n; i++)
for(int j=0; j<=m; j++)
for(int h=1; h<=tot; h++)
if( st[h][9] < bit[m+1] )
{
if(dp[i][j][h]==0) continue;
int x = st[h][j];
int y = st[h][j+1];
int k = st[h][9];
if(i==n && j==m) break;
if (j == m)
{
if (st[h][m] == 0) dp[i+1][0][ go[k*3] ] += dp[i][j][h];
continue;
}
if (ok[i][j+1] == '#')
{
if (x == 0 && y == 0)
dp[i][j+1][h] += dp[i][j][h];
continue;
}
if (y == 0 && y == 0)
dp[i][j+1][ go[ k+bit[j]+2*bit[j+1] ] ] += dp[i][j][h];
else if(x==0 || y==0)
{
dp[i][j+1][h] += dp[i][j][h];
if(x==0)
dp[i][j+1][ go[ k-y*bit[j+1]+y*bit[j] ] ] += dp[i][j][h];
else
dp[i][j+1][ go[ k-x*bit[j]+x*bit[j+1] ] ] += dp[i][j][h];
}
else if (x ==2 && y==1)
dp[i][j+1][ go[ k - x*bit[j] - y*bit[j+1] ] ] += dp[i][j][h];
else if (x == 1 && y==1)
dp[i][j+1][ go[ k - x*bit[j] - y*bit[j+1] - bit[p[h][j+1] ] ] ] += dp[i][j][h];
else if (x == 2 && y==2)
dp[i][j+1][ go[ k - x*bit[j] - y*bit[j+1] + bit[ p[h][j] ] ] ] += dp[i][j][h];
}
printf("%d\n", dp[n][m][ go[ 1 + 2 * bit[m-1] ] ]);
}
return 0;
}
POJ-1739-插头dp
最新推荐文章于 2020-08-27 12:21:46 发布