zoukankan      html  css  js  c++  java
  • POJ 1038 Bugs Integrated(状态压缩DP)

    题意:

    将 2*3 的芯片嵌入 n*m 的单位尺寸模板中,模板上面有一些坏点将被标记出,求最大的芯片数量。

    黑书 138 页的例题, CEOI 2002;

    思路:

    1. 由于 m <= 10,所以可以针对每一行看成一个整体,根据情况来产生一个状态,首先肯定是枚举当前行的状态,来产生下一行的状态了,时间复杂度为O(nm3m);

    2. 递推的过程中,因为是由一个已知状态,转移到多个未知状态,如何产生这多个未知状态?这里采用 DFS 的方式,提供了 2 个数组 Q,随时存储和恢复状态;

    3. Q[1][i] 代表当前行的摆放情况, Q[0][i] 代表上一行的摆放情况。并且值为 0,1,2 如黑书上面描述的一样。采用 3 进制表示法,因为如果用 2 个二进制位表示,总共可能会达到 20 位,这样会产生很大的内存浪费;

    4. 因为当前行的状态以及值,都是由上一行的情况转移过来的,所以利用滚动数组,可以有效的节省内存,注意每次要置 -1 即可。

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    bool grid[160][12];
    int row, col, Q[2][12], dp[2][60000];
    
    void backstate(int s, int f[]) {
        for (int i = 0; i < col; i++) {
            f[i] = s % 3; s /= 3;
        }
    }
    
    int getstate(int f[]) {
        int ans = 0;
        for (int i = col-1; i >= 0; i--) {
            ans *= 3;
            ans += f[i];
        }
        return ans;
    }
    
    int T1, T2;
    
    void dfs(int i, int count, int state) {
        if (i > col - 1)
            return;
    
        if (i+2 < col && Q[1][i] == 0 && Q[1][i+1] == 0 && Q[1][i+2] == 0) {
            Q[1][i] = Q[1][i+1] = Q[1][i+2] = 2;
            int now = getstate(Q[1]);
            dp[T2][now] = max(dp[T2][now], count+1);
            dfs(i+3, count+1, now);
            Q[1][i] = Q[1][i+1] = Q[1][i+2] = 0;
        }
    
        if (i+1 < col && Q[1][i] == 0 && Q[1][i+1] == 0 && Q[0][i] == 0 && Q[0][i+1] == 0) {
            Q[1][i] = Q[1][i+1] = 2;
            int now = getstate(Q[1]);
            dp[T2][now] = max(dp[T2][now], count+1);
            dfs(i+2, count+1, now);
            Q[1][i] = Q[1][i+1] = 0;
        }
    
        dp[T2][state] = max(dp[T2][state], dp[T1][getstate(Q[0])]);
        dfs(i+1, count, state);
    }
    
    int solvedp() {
        int endstate = 1;
        for (int i = 0; i < col; i++)
            endstate *= 3;
    
        for (int i = 0; i < col; i++)
            Q[1][i] = grid[0][i] ? 2 : 1;
        memset(dp[0], -1, sizeof(dp[0]));
        dp[0][getstate(Q[1])] = 0;
            
        T1 = 1, T2 = 0;
        for (int i = 1; i < row; i++) {
            T1 ^= 1, T2 ^= 1;
            memset(dp[T2], -1, sizeof(dp[0]));
            for (int s = 0; s < endstate; s++) {
                if (dp[T1][s] == -1)
                    continue;
                backstate(s, Q[0]);
                for (int j = 0; j < col; j++) {
                    Q[1][j] = grid[i][j] ? 2 : Q[0][j]-1;
                    if (Q[1][j] < 0) Q[1][j] = 0;
                }
                dfs(0, dp[T1][s], getstate(Q[1]));
            }
        }
        int ans = -1;
        for (int s = 0; s < endstate; s++)
            ans = max(ans, dp[T2][s]);
        return ans;
    }
    
    int main() {
        int cases;
        scanf("%d", &cases);
        while (cases--) {
            int tag;
            scanf("%d%d%d", &row, &col, &tag);
            memset(grid, false, sizeof(grid));
            for (int i = 0; i < tag; i++) {
                int x, y;
                scanf("%d%d", &x, &y);
                grid[x-1][y-1] = true;
            }
            printf("%d\n", solvedp());
        }
        return 0;
    }
    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    算法
    Unity-UI
    lua-设计与实现 1类型
    Unity-Cache Server
    lua-高效编程-总结
    算法-JPS寻路设计思想
    数据结构- List、Dictionary
    数据结构-二叉树、堆
    VSCode更好用
    功能快捷键
  • 原文地址:https://www.cnblogs.com/kedebug/p/3001147.html
Copyright © 2011-2022 走看看