zoukankan      html  css  js  c++  java
  • URAL 1519 Formula 1

    URAL_1519

        插头dp的处女作终于完成啦^_^

        具体的思路还是参考陈丹琦的论文吧,我也只是处于学习和模仿的阶段。我是仿照胡浩博客用最小表示法敲的代码,更多和插头dp相关的内容可以参考胡浩的博客:http://www.notonlysuccess.com/index.php/plug-dp-complete/

    #include<stdio.h>
    #include<string.h>
    #define MAXD 15
    #define HASH 30007
    #define SIZE 1000010
    int N, M, maze[MAXD][MAXD], code[MAXD], ch[MAXD], ex, ey;
    char b[MAXD];
    struct Hashmap
    {
        int size, head[HASH], next[SIZE];
        long long f[SIZE], state[SIZE];
        void init()
        {
            memset(head, -1, sizeof(head));
            size = 0;
        }
        void push(long long st, long long ans)
        {
            int i, h = st % HASH;
            for(i = head[h]; i != -1; i = next[i])
                if(state[i] == st)
                {
                    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, long long st)
    {
        int i;
        for(i = m; i >= 0; i --)
        {
            code[i] = st & 7;
            st >>= 3;
        }
    }
    long long encode(int *code, int m)
    {
        int i, cnt = 1;
        long long st = 0;
        memset(ch, -1, sizeof(ch));
        ch[0] = 0;
        for(i = 0; i <= m; i ++)
        {
            if(ch[code[i]] == -1)
                ch[code[i]] = cnt ++;
            code[i] = ch[code[i]];
            st <<= 3;
            st |= code[i];
        }
        return st;
    }
    void init()
    {
        int i, j, k;
        memset(maze, 0, sizeof(maze));
        ex = 0;
        for(i = 1; i <= N; i ++)
        {
            scanf("%s", b + 1);
            for(j = 1; j <= M; j ++)
                if(b[j] == '.')
                    maze[ex = i][ey = j] = 1;
        }
    }
    void shift(int *code, int m)
    {
        int i;
        for(i = m; i > 0; i --)
            code[i] = code[i - 1];
        code[0] = 0;
    }
    void dpblank(int i, int j, int cur)
    {
        int k, t, left, up;
        for(k = 0; k < hm[cur].size; k ++)
        {
            decode(code, M, hm[cur].state[k]);
            left = code[j - 1], up = code[j];
            if(left && up) // case 1
            {
                if(left == up)
                {
                    if(i == ex && j == ey)
                    {
                        code[j - 1] = code[j] = 0;
                        if(j == M)
                            shift(code, M);
                        hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
                    }
                }
                else
                {
                    code[j - 1] = code[j] = 0;
                    for(t = 0; t <= M; t ++)
                        if(code[t] == up)
                            code[t] = left;
                    if(j == M)
                        shift(code, M);
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
                }
            }
            else if(left) // case 2
            {
                if(maze[i][j + 1])
                {
                    code[j - 1] = 0, code[j] = left;
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
                }
                if(maze[i + 1][j])
                {
                    code[j - 1] = left, code[j] = 0;
                    if(j == M)
                        shift(code, M);
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
                }
            }
            else if(up) // case 3
            {
                if(maze[i][j + 1])
                {
                    code[j - 1] = 0, code[j] = up;
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
                }
                if(maze[i + 1][j])
                {
                    code[j - 1] = up, code[j] = 0;
                    if(j == M)
                        shift(code, M);
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
                }
            }
            else // case 4
            {
                if(maze[i][j + 1] && maze[i + 1][j])
                {
                    code[j - 1] = code[j] = 13;
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
                }
            }
        }
    }
    void dpblock(int i, int j, int cur)
    {
        int k;
        for(k = 0; k < hm[cur].size; k ++)
        {
            decode(code, M, hm[cur].state[k]);
            code[j - 1] = code[j] = 0;
            if(j == M)
                shift(code, M);
            hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]);
        }
    }
    void solve()
    {
        int i, j, cur = 0;
        long long ans = 0;
        hm[cur].init();
        hm[cur].push(0, 1);
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
            {
                hm[cur ^ 1].init();
                if(maze[i][j])
                    dpblank(i, j, cur);
                else
                    dpblock(i, j, cur);
                cur ^= 1;
            }
        for(i = 0; i < hm[cur].size; i ++)
            ans += hm[cur].f[i];
        printf("%lld\n", ans);
    }
    int main()
    {
        while(scanf("%d%d", &N, &M) == 2)
        {
            init();
            if(ex == 0)
                printf("0\n");
            else
                solve();
        }
        return 0;
    }
  • 相关阅读:
    How to function call using 'this' inside forEach loop
    jquery.validate.unobtrusive not working with dynamic injected elements
    Difference between jQuery.extend and jQuery.fn.extend?
    Methods, Computed, and Watchers in Vue.js
    Caution using watchers for objects in Vue
    How to Watch Deep Data Structures in Vue (Arrays and Objects)
    Page: DOMContentLoaded, load, beforeunload, unload
    linux bridge
    linux bridge
    EVE-NG网卡桥接
  • 原文地址:https://www.cnblogs.com/staginner/p/2455947.html
Copyright © 2011-2022 走看看