zoukankan      html  css  js  c++  java
  • HDU 1964 Pipes

    HDU_1964

        这个题目只需要把求回路数量的dp方程改写成取最优解的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
    #define INF 0x3f3f3f3f
    int N, M, code[MAXD], ch[MAXD], maze[MAXD][MAXD], rcost[MAXD][MAXD], dcost[MAXD][MAXD];
    char b[50];
    struct Hashmap
    {
        int head[HASH], next[SIZE], state[SIZE], f[SIZE], size;
        void init()
        {
            memset(head, -1, sizeof(head));
            size = 0;
        }
        void push(int st, int ans)
        {
            int i, h = st % HASH;
            for(i = head[h]; i != -1; i = next[i])
                if(state[i] == st)
                {
                    if(ans < f[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;
        for(i = m; i >= 0; i --)
        {
            code[i] = st & 7;
            st >>= 3;
        }
    }
    int encode(int *code, int m)
    {
        int i, cnt = 0, 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;
        gets(b), sscanf(b, "%d%d", &N, &M);
        memset(maze, 0, sizeof(maze));
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
                maze[i][j] = 1;
        gets(b);
        for(i = 1; i < 2 * N; i ++)
        {
            gets(b);
            if(i & 1)
            {
                for(j = 1, k = 2; k < 2 * M; j ++, k += 2)
                    rcost[(i + 1) >> 1][j] = b[k] - '0';
            }
            else
            {
                for(j = 1, k = 1; k < 2 * M; j ++, k += 2)
                    dcost[i >> 1][j] = b[k] - '0';
            }
        }
        gets(b);
    }
    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, left, up, t;
        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)
            {
                if(left == up)
                {
                    if(i == N && j == M)
                    {
                        code[j - 1] = code[j] = 0;
                        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 || up)
            {
                if(maze[i][j + 1])
                {
                    code[j - 1] = 0, code[j] = left + up;
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k] + rcost[i][j]);
                }
                if(maze[i + 1][j])
                {
                    code[j - 1] = left + up, code[j] = 0;
                    if(j == M)
                        shift(code, M);
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k] + dcost[i][j]);
                }
            }
            else
            {
                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] + rcost[i][j] + dcost[i][j]);
                }
            }
        }
    }
    void solve()
    {
        int i, j, cur = 0, ans = INF;
        hm[cur].init();
        hm[cur].push(0, 0);
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
            {
                hm[cur ^ 1].init();
                dpblank(i, j, cur);
                cur ^= 1;
            }
        for(i = 0; i < hm[cur].size; i ++)
            if(hm[cur].f[i] < ans)
                ans = hm[cur].f[i];
        printf("%d\n", ans);
    }
    int main()
    {
        int t;
        gets(b), sscanf(b, "%d", &t);
        while(t --)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    HDU2059(龟兔赛跑)
    pat 1012 The Best Rank
    pat 1010 Radix
    pat 1007 Maximum Subsequence Sum
    pat 1005 Sign In and Sign Out
    pat 1005 Spell It Right
    pat 1004 Counting Leaves
    1003 Emergency
    第7章 输入/输出系统
    第六章 总线
  • 原文地址:https://www.cnblogs.com/staginner/p/2458695.html
Copyright © 2011-2022 走看看