• HDU 2442 Bricks


    HDU_2442

        如果用递推形式的dp的话,需要记录两行轮廓线的状态,然后根据状态逐格dp,逐一讨论每个图形是否能够嵌入到当前状态中。

        由于写搓了,直接交的时候TLE了,所以就干脆先将所有状态预处理出来了,然后每次O(1)输出正确结果。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXN 110
    #define MAXM 6
    #define ST 4096
    int N, M, D, f[MAXN][MAXM][ST], dp[MAXN][MAXM];
    void prepare(int N, int M)
    {
        int i, j, k;
        for(i = 0, D = 1; i < M; i ++) D <<= 2;
        for(i = 0; i <= N; i ++)
            for(j = 0; j < M; j ++)
                for(k = 0; k < D; k ++) f[i][j][k] = 0;
        f[i][j][0] = 0;
        for(i = 0; i < N; i ++)
        {
            for(j = 0; j < M; j ++)
                for(k = 0; k < D; k ++)
                {
                    int st;
                    st = ~(3 << 2 * j) & k | (1 << 2 * j & k) << 1 | 1 << 2 * j;
                    if(j == M - 1) f[i + 1][0][st] = std::max(f[i + 1][0][st], f[i][j][k]);
                    else f[i][j + 1][st] = std::max(f[i][j + 1][st], f[i][j][k]);
    
                    if(i >= 2 && j < M - 1 && (k >> 2 * j & 7) == 7)
                    {
                        st = k & ~(7 << 2 * j);
                        f[i][j + 1][st] = std::max(f[i][j + 1][st], f[i][j][k] + 4);
                    }
    
                    if(i >= 2 && j >= 1 && j < M - 1 && (k >> 2 * j - 1 & 15) == 15)
                    {
                        st = k & ~(15 << 2 * j - 1);
                        f[i][j + 1][st] = std::max(f[i][j + 1][st], f[i][j][k] + 5);
                    }
    
                    if(i >= 1 && j >= 1 && j < M - 1 && (k & 1 << 2 * j - 1) && (k & 1 << 2 * j) && (k & 1 << 2 * j + 2))
                    {
                        st = k & ~(1 << 2 * j + 1) ^ 1 << 2 * j - 1 ^ 1 << 2 * j ^ 1 << 2 * j + 2;
                        f[i][j + 1][st] = std::max(f[i][j + 1][st], f[i][j][k] + 4);
                    }
    
                    if(i >= 1 && j < M - 2 && (k & 1 << 2 * j) && (k & 1 << 2 * j + 2) && (k & 1 << 2 * j + 4))
                    {
                        st = k & ~(1 << 2 * j + 1) ^ 1 << 2 * j ^ 1 << 2 * j + 2 ^ 1 << 2 * j + 4;
                        f[i][j + 1][st] = std::max(f[i][j + 1][st], f[i][j][k] + 4);
                    }
    
                    if(i >= 2 && j < M - 1 && (k & 1 << 2 * j) && (k & 1 << 2 * j + 1) && (k & 1 << 2 * j + 3))
                    {
                        st = k ^ 1 << 2 * j ^ 1 << 2 * j + 1 ^ 1 << 2 * j + 3;
                        f[i][j + 1][st] = std::max(f[i][j + 1][st], f[i][j][k] + 4);
                    }
                }
            for(k = 0, dp[i][M - 1] = 0; k < D; k ++) dp[i][M - 1] = std::max(dp[i][M - 1], f[i + 1][0][k]);
        }
    }
    int main()
    {
        memset(dp, 0, sizeof(dp));
        for(int i = 2; i <= 6; i ++) prepare(100, i);
        while(scanf("%d%d", &N, &M) == 2)
        {
            printf("%d\n", dp[N - 1][M - 1]);
        }
        return 0;
    }
  • 相关阅读:
    CSS开发中常用技巧总结
    Linq的分组功能
    深入理解 C# 协变和逆变
    js数组删除数组元素!
    关于 Photoshop 蒙版和 Alpha 通道
    jQuery数组处理详解(含实例演示)
    多媒体指令(灰度像素最大值)
    多媒体指令(图像均值模糊)
    matlab练习程序(立体相关块匹配)
    matlab练习程序(steerable filters)
  • 原文地址:https://www.cnblogs.com/staginner/p/2671237.html
Copyright © 2020-2023  润新知