• SGU 223 Little Kings


    SGU_223

    最近刚学了插头dp,所以就用插头dp那个模式写了这个题。

    如果逐格递推的话实际上只有这个格子左边、左上方、上方、右上方的格子会影响当前这个格子是否能够放king,所以在记录状态的时候可以把轮廓线上有无king作为一个状态,同时单记录轮廓线上的king没办法知道最后有多少个king,所以再在状态中留出7个二进制位记录一下已经放了几个king即可。

    #include<stdio.h>
    #include<string.h>
    #define HASH 30007
    #define SIZE 1000010
    #define MAXD 15
    int N, K, code[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;
        }
        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];
    void decode(int *code, int m, int st)
    {
        int i;
        num = st & ((1 << 7) - 1);
        st >>= 7;
        for(i = m; i >= 0; i --)
        {
            code[i] = st & 1;
            st >>= 1;
        }
    }
    int encode(int *code, int m)
    {
        int i, st = 0;
        for(i = 0; i <= m; i ++)
        {
            st <<= 1;
            st |= code[i];
        }
        st <<= 7;
        st |= num;
        return st;
    }
    void dpblank(int i, int j, int cur)
    {
        int k;
        for(k = 0; k < hm[cur].size; k ++)
        {
            decode(code, N + 1, hm[cur].state[k]);
            if(num < K && code[j - 1] == 0 && code[j] == 0 && code[j + 1] == 0 && code[j + 2] == 0)
            {
                ++ num;
                code[j] = 1;
                hm[cur ^ 1].push(encode(code, j == N ? N : N + 1), hm[cur].f[k]);
                -- num;
            }
            code[j] = 0;
            hm[cur ^ 1].push(encode(code, j == N ? N : N + 1), hm[cur].f[k]);
        }
    }
    void solve()
    {
        int i, j, cur = 0;
        long long ans = 0;
        hm[cur].init();
        hm[cur].push(0, 1);
        memset(code, 0, sizeof(code));
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= N; j ++)
            {
                hm[cur ^ 1].init();
                dpblank(i, j, 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\n", ans);
    }
    int main()
    {
        while(scanf("%d%d", &N, &K) == 2)
        {
            solve();
        }
        return 0;
    }
  • 相关阅读:
    关于此博客的制作
    Java线程运行轨迹-代码追踪与定位
    MySQL安装和使用
    jenkins安装和使用教程
    持续集成(git+TortoiseGit+Gitblit)
    RF框架基础知识(二)
    RF工具ride使用
    Postman的使用
    用Python写RF测试
    RF框架基础知识(一)
  • 原文地址:https://www.cnblogs.com/staginner/p/2461733.html
Copyright © 2020-2023  润新知