zoukankan      html  css  js  c++  java
  • POJ 1038 Bugs Integrated, Inc.(DFS + 三进制状压 + 滚动数组 思维)题解

    题意:n*m方格,有些格子有黑点,问你最多裁处几张2 * 3(3 * 2)的无黑点格子。

    思路:我们放置2 * 3格子时可以把状态压缩到三进制:

    关于状压:POJ-1038 Bugs Integrated, Inc. (状压+滚动数组+深搜 的动态规划),写的很详细

    所以我们直接枚举每一行的所有可能状态,并算出每种状态最大值。这样我们到最后只要找到n行所有状态最大值就行了。

    代码:

    #include<cmath>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 150 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1000000007;
    int dp[2][60000], ter[15];
    int vis[160][15];
    int t, n, m, k;
    int now[15], pre[15];
    void getNow(int i){
        for(int k = 1; k <= m; k++){
            if(vis[i][k]){
                now[k] = 2;
            }
            else{
                if(pre[k] <= 1) now[k] = 0;
                else now[k] = 1;
            }
        }
    }
    int getSt(){
        int ret = 0;
        for(int k = 1; k <= m; k++){
            ret = ret * 3 + now[k];
        }
        return ret;
    }
    void dfs(int i, int j, int num){
        int nowSt;
    
        if(j > m){
            nowSt = getSt();
            dp[i % 2][nowSt] = max(dp[i % 2][nowSt], num);
            return;
        }
    
        // ▇ ▇ ▇
        // ▇ ▇ ▇
        if(j >= 3 && !now[j - 2] && !now[j - 1] && !now[j]){
            now[j - 2] = now[j - 1] = now[j] = 2;
            nowSt = getSt();
            dp[i % 2][nowSt] = max(dp[i % 2][nowSt], num + 1);
            dfs(i, j + 2, num + 1);
            now[j - 2] = now[j - 1] = now[j] = 0;
        }
    
        // ▇ ▇
        // ▇ ▇
        // ▇ ▇
        if(j >= 2 && !now[j - 1] && !now[j] && !pre[j - 1] && !pre[j]){
            now[j - 1] = now[j] = 2;
            nowSt = getSt();
            dp[i % 2][nowSt] = max(dp[i % 2][nowSt], num + 1);
            dfs(i, j + 2, num + 1);
            now[j - 1] = now[j] = 0;
        }
    
        nowSt = getSt();
        dp[i % 2][nowSt] = max(dp[i % 2][nowSt], num);
        dfs(i, j + 1, num);
    }
    int main(){
        ter[0] = 1;
        for(int i = 1; i <= 12; i++){
            ter[i] = ter[i - 1] * 3;
        }
        scanf("%d", &t);
        while(t--){
            scanf("%d%d%d", &n, &m, &k);
            memset(vis, 0, sizeof(vis));
            for(int i = 1; i <= k; i++){
                int x, y;
                scanf("%d%d", &x, &y);
                vis[x][y] = 1;
            }
    
            //0 都可以,1 上一行不可以,2 都不可以
            int temp = 0;
            for(int i = 1; i <= m; i++) temp = temp * 3 + 2;
            memset(dp[0], -1, sizeof(dp[0]));
            dp[0][temp] = 0;
            for(int i = 1; i <= n; i++){
                memset(dp[i % 2], -1, sizeof(dp[0]));
                for(int st = 0; st < ter[m]; st++){
                    if(dp[(i + 1) % 2][st] == -1) continue;
                    int tmp = st;
                    for(int j = m; j >= 1; j--){
                        pre[j] = tmp % 3;
                        tmp /= 3;
                    }
                    getNow(i);
                    dfs(i, 1, dp[(i + 1) % 2][st]);
                }
            }
    
            int Max = -1;
            for(int i = 0; i < ter[m]; i++)
                Max = max(Max, dp[n % 2][i]);
            printf("%d
    ", Max);
        }
        return 0;
    }
  • 相关阅读:
    wampserver2.6下UCenter1.6.0与UCenter Home2.0整合安装
    wampserver环境下,安装ucenter1.6.0
    wampserver环境下,apache本地下设置多个域名
    sqlserver中索引优化
    wampserver,eclipse,PHPeclipse搭建php开发环境
    [phonegap]安装phonegap
    有用的开源软件
    删除用户的时候,产生“数据库主体在该数据库中拥有架构,无法删除”的解决办法
    工作流图形设计器参考资料
    将 IDENTITY 转换为数据类型 int 时出现算术溢出错误。
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10659856.html
Copyright © 2011-2022 走看看