郑厂长系列故事——N骑士问题

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1<<8
#define max(x,y) x > y ? x : y 
#define J(u,d,k) !((u>>k)&d) && !((u<<k)&d) 

int n, num[MAXN], ins[9] ;
int dp[9][11][MAXN][MAXN] ;
int s[9][MAXN] ;

void getTable()
{
    int i, j, k ;
    for(i = 1 ; i <= 8 ; i ++)
    {
        for(k = j = 0 ; j < MAXN ; j ++)
            if(!(j&ins[i]) ) s[i][++k] = j ;
        s[i][0] = k ;
    }
}
int stateDP()
{
    int i, j, k, l, x, y ; 
    int ans = 0 ;
    memset(dp, 0, sizeof(dp)) ;
    for(i = 1 ; i <= s[1][0] ; i ++)
        for(j = 1 ; j <= s[2][0] ; j ++) 
            if(J(s[1][i], s[2][j], 2)) dp[2][ num[s[1][i]]+num[s[2][j]] ][i][j] = 1 ;
    for(i = 3 ; i <= 8 ; i ++)
    {
        for(j = 1 ; j <= s[i-1][0] ; j ++)
            for(k = 1 ; k <= s[i][0] ; k ++) 
            {
                if(!J(s[i-1][j], s[i][k], 2)) continue ;
                x = num[s[i-1][j]] + num[s[i][k]] ;//
                for( ; x <= n ; x ++ ) 
                {
                    for(l = 1 ; l <= s[i-2][0] ; l ++)
                        if(J(s[i-2][l], s[i][k], 1) && J(s[i-2][l], s[i-1][j], 2))
                        {
                            dp[i][x][j][k] += dp[i-1][ x-num[s[i][k]] ][l][j] ;
                        }
                }
            }
    }
    for(i = 1 ; i <= s[7][0] ; i ++)
        for(j = 1 ; j <= s[8][0] ; j ++)
            if(J(s[7][i], s[8][j], 2))ans += dp[8][n][i][j] ;
    return ans ;
}

int main()
{
    int i, j, T ;
    char str[10] ;
    for(i = 0 ; i < MAXN ; i ++)
        for(num[i] = j = 0 ; j < 8 ; j ++) num[i] = i&(1<<j) ? num[i]+1 : num[i] ;
    scanf("%d", &T) ;
    while(T --)
    {
        scanf("%d", &n) ;
        for(i = 1 ; i <= 8 ; i ++)
        {
            scanf("%s", str) ;
            for(ins[i] = j = 0 ; j < 8 ; j ++) ins[i] = (str[j] == '*') ? ins[i]+(1<<j) : ins[i] ;
        }
        getTable() ;
        printf("%d\n", stateDP()) ;
    }
    return 0 ;
}

 

posted @ 2013-03-31 18:25  安月天下  阅读(293)  评论(0编辑  收藏  举报