SGU 225 Little Knights

 SGU_225

由于在dp的时候需要记录上面两行放置马的状态,以及马的数量,这样状态数就相当多了,直接交写完的dpTLE了。

暂时没有想到好的办法,所以拿自己dp的程序打了个表交上去AC了。

// 注意:这个程序是用来打表的,并不是可以直接提交的程序。

#include<stdio.h>

#include<string.h>

#define MAXD 20

#define HASH 100007

#define SIZE 2000010

int N, K, ucode[MAXD], dcode[MAXD], ncode[MAXD], num;

struct Hashmap

{

    int head[HASH], next[SIZE], state[SIZE], size;

    long long f[SIZE];

    void init()

    {

        memset(head, -1, sizeof(head));

        size = 0;

    }

    inline void push(int st, long long ans)

    {

        int i, h = st % HASH;

        for(i = head[h]; i != -1; i = next[i])

        {

            if(st == state[i])

            {

                f[i] += ans;

                return ;

            }

        }

        state[size] = st, f[size] = ans;

        next[size] = head[h];

        head[h] = size ++;

    }

}hm[2];

inline void decode(int *ucode, int *dcode, int m, int st)

{

    int i;

    num = st & ((1 << 7) - 1);

    st >>= 7;

    for(i = m; i >= 0; i --)

    {

        dcode[i] = st & 1;

        st >>= 1;

    }

    for(i = m; i >= 0; i --)

    {

        ucode[i] = st & 1;

        st >>= 1;

    }

}

inline int encode(int *ucode, int *dcode, int m)

{

    int i, st = 0;

    for(i = 0; i <= m; i ++)

    {

        st <<= 1;

        st |= ucode[i];

    }

    for(i = 0; i <= m; i ++)

    {

        st <<= 1;

        st |= dcode[i];

    }

    st <<= 7;

    st |= num;

    return st;

}

void dfs(int cur, int k, int j)

{

    if(j > N)

    {

        hm[cur ^ 1].push(encode(dcode, ncode, N + 1), hm[cur].f[k]);

        return ;

    }

    if(num < K && dcode[j - 1] == 0 && ucode[j] == 0 && ucode[j + 2] == 0 && dcode[j + 3] == 0)

    {

        ++ num;

        ncode[j + 1] = 1;

        dfs(cur, k, j + 1);

        -- num;

    }

    ncode[j + 1] = 0;

    dfs(cur, k, j + 1);

}

void dpblank(int cur)

{

    int k;

    for(k = 0; k < hm[cur].size; k ++)

    {

        decode(ucode, dcode, N + 1, hm[cur].state[k]);

        dfs(cur, k, 1);

    }

}

void solve()

{

    int i, j, cur = 0;

    long long ans = 0;

    hm[cur].init();

    hm[cur].push(0, 1);

    memset(ucode, 0, sizeof(ucode));

    memset(dcode, 0, sizeof(dcode));

    memset(ncode, 0, sizeof(ncode));

    for(i = 1; i <= N; i ++)

    {

        hm[cur ^ 1].init();

        dpblank(cur);

        cur ^= 1;

    }

    for(i = 0; i < hm[cur].size; i ++)

        if((hm[cur].state[i] & ((1 << 7) - 1)) == K)

            ans += hm[cur].f[i];

    printf("%I64d", ans);

}

int main()

{

    freopen("SGU_225(1).cpp", "w", stdout);

    printf("#include<stdio.h>\n");

    printf("#include<string.h>\n");

    printf("#define MAXD 110\n");

    printf("int N, K;\n");

    printf("long long ans[MAXD][MAXD];\n");

    printf("int main()\n");

    printf("{\n");

    for(N = 1; N <= 10; N ++)

        for(K = 1; K <= N * N; K ++)

        {

            printf("\tans[%d][%d] = ", N, K);

            if(N > 3 && K > (N * N + 1) / 2)

                printf("0");

            else

                solve();

            printf("ll;\n");

        }

    printf("\twhile(scanf(\"%%d%%d\", &N, &K) == 2)\n");

    printf("\t{\n");

    printf("\t\tprintf(\"%%I64d\\n\", K == 0 ? 1 : ans[N][K]);\n");

    printf("\t}\n");

    printf("\treturn 0;\n");

    printf("}\n");

    return 0;

}

 

你可能感兴趣的:(it)