zoukankan      html  css  js  c++  java
  • HDU 3377 Plan

    HDU_3377

        这个题目本质上还是一个回路的问题,为了方便处理,可以把初始状态看成只有左上角上方的位置有个下插头,同时把右下角下方的格子看成可以继续走的格子。

        由于不一定每个格子都走,所以可以在递推到既没有上插头也没有下插头的格子时额外加一种情况——在这个格子不加任何插头(也就是说不会经过这个格子)。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 15
    #define HASH 30007
    #define SIZE 1000010
    int N, M, maze[MAXD][MAXD], score[MAXD][MAXD], code[MAXD], ch[MAXD];
    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(st == state[i])
                {
                    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 = 1, 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;
        memset(maze, 0, sizeof(maze));
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
            {
                scanf("%d", &score[i][j]);
                maze[i][j] = 1;
            }
        maze[N + 1][M] = 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, 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)
                {
                    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] + score[i][j]);
                }
            }
            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] + score[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] + score[i][j]);
                }
            }
            else
            {
                if(maze[i + 1][j] && maze[i][j + 1])
                {
                    code[j - 1] = code[j] = 13;
                    hm[cur ^ 1].push(encode(code, M), hm[cur].f[k] + score[i][j]);
                }
                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;
        hm[cur].init();
        memset(code, 0, sizeof(code));
        code[1] = 1;
        hm[cur].push(encode(code, M), 0);
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
            {
                hm[cur ^ 1].init();
                dpblank(i, j, cur);
                cur ^= 1;
            }
        printf("%d\n", hm[cur].f[0]);
    }
    int main()
    {
        int t = 0;
        while(scanf("%d%d", &N, &M) == 2)
        {
            init();
            printf("Case %d: ", ++ t);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    疫情环境下的网络学习笔记 python 5.8 数据库入门终章
    疫情环境下的网络学习笔记 python 5.7 navicat数据库,例题,sql注入
    疫情环境下的网络学习笔记 python 5.6 暂时看看
    疫情环境下的网络学习笔记 python 5.5 MYSql 表关系,外键
    疫情环境下的网络学习笔记 python 5.4 数据库基础
    疫情环境下的网络学习笔记 python 4.30 初识数据库
    疫情环境下的网络学习笔记 python 4.29 网络小项目
    XJOI 夏令营501-511测试11 游戏
    XJOI 夏令营501-511测试11 统计方案
    CF1197D Yet Another Subarray Problem
  • 原文地址:https://www.cnblogs.com/staginner/p/2459469.html
Copyright © 2011-2022 走看看