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;
}
原文地址:https://www.cnblogs.com/staginner/p/2462334.html