现在的位置: 首页 > 综合 > 正文

POJ-1739-插头dp

2013年06月23日 ⁄ 综合 ⁄ 共 1511字 ⁄ 字号 评论关闭
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;
}

抱歉!评论已关闭.