zoukankan      html  css  js  c++  java
  • poj1038 Bugs Integrated, Inc.

    讲解推荐这位的 http://www.cnblogs.com/dengeven/p/3237382.html

    如果你手上有lrj的黑书, 那么黑书上也有讲解.


    二进制状压练得挺熟, 但是一直没有时间好好研究三进制状压。

    于是找了个题目学习了一下, 两天里修修补补总算AC了。

    有几个收获。

    1. 三进制与十进制的转换的小技巧(利用数组)

    2. 刷表法时, 用dfs来更新状态。这种更新状态的方式蛮新颖的,我这种蒟蒻还是第一次遇见。

    3. 还是更新状态。可以先把新状态算出来,再来枚举决策。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int MAXN = 150 + 5;
    const int MAXM = 10  + 2;
    
    int N, M, K;
    bool badp[MAXN][MAXM];
    int p[12] = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049};
    int f[2][60000];
    
    inline int threetoten(int a[]){
        int tmp = 0;
        for(int i = 0; i < M; i++)
            tmp += a[i] * p[i];
        return tmp;
    }
    
    inline void tentothree(int x, int a[]){
        for(int i = 0; i < M; i++)
            a[i] = x % 3, x /= 3;
    }
    
    int pre[13], cur[13];
    void dfs(int d, int j, int last, int state)
    {
        int k;
        f[d][state] = max(f[d][state], last);
        if(j >= M) return ;
        if((j + 1) < M && (pre[j] == 0) && (pre[j + 1] == 0) && (cur[j] == 0) && (cur[j + 1] == 0)){
            cur[j] = cur[j + 1] = 2;
            k = threetoten(cur);
            dfs(d, j + 2, last + 1, k);
            cur[j] = cur[j + 1] = 0;
        }
        if((j + 2) < M && (cur[j] == 0) && (cur[j + 1] == 0) && (cur[j + 2] == 0)){
            cur[j] = cur[j + 1] = cur[j + 2] = 2;
            k = threetoten(cur);
            dfs(d, j + 3, last + 1, k);
            cur[j] = cur[j + 1] = cur[j + 2] = 0;
        }
        dfs(d, j + 1, last, state);
        return ;
    }
    
    int solve()
    {
        int d = 0; int tmp;
        memset(f[d], -1, sizeof(f[d]));
        for(int i = 0; i < M; i++) pre[i] = (badp[1][i] ? 2 : 1);
        tmp = threetoten(pre);
        f[d][tmp] = 0;
    
        for(int i = 2; i <= N; i++){
            d ^= 1;
            memset(f[d], -1, sizeof(f[d]));
    
            for(int j = 0; j < p[M]; j++){
                if(f[d ^ 1][j] == -1) continue;
                tentothree(j, pre);
                for(int k = 0; k < M; k++){
                    if(badp[i][k]) cur[k] = 2;
                    else cur[k] = (pre[k] == 0 ? 0 : pre[k] - 1);
                }
    
                tmp = threetoten(cur);
                dfs(d, 0, f[d ^ 1][j], tmp);
            }
        }
        int ans = 0;
        for(int i = 0; i < p[M]; i++) ans = max(ans, f[d][i]);
        return ans;
    }
    
    int main()
    {
        int T; cin>>T;
        while(T--)
        {
            cin>>N>>M>>K;
            memset(badp, false, sizeof(badp));
            for(int i = 1, x, y; i <= K; i++){
                scanf("%d%d", &x, &y);
                badp[x][y - 1] = true;
            }
            printf("%d
    ", solve());
        }
        return 0;
    }
  • 相关阅读:
    URL 编码通用引用
    [转]Asp.Net 301重定向的实现(SEO友好,有利于PR值)
    js重载图片
    Asp.net MVC学习
    SEO分析的七个切入角度
    [C#] 注入DLL
    [C] 伽马函数计算(可求小数)
    [C++] DLL远程注入实例
    [JS] 玩转微软Bing地图
    [C#(WebForm)] (开源)仿VS.NET的在线网页编辑器(Lesktop开源控件库)
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9281425.html
Copyright © 2011-2022 走看看