zoukankan      html  css  js  c++  java
  • poj 1308Bugs Integrated, Inc. [三进制状压]

    题目链接【http://poj.org/problem?id=1038】

    题意: 给出一个N*M大小的图,图中有K个坏点。N (1 <= N <= 150), M (1 <= M <= 10), K (0 <= K <= MN);用2*3和3*2的木块去填这个图,问最多能放多少个木块。

    题解:用一个三进制数表示某一行的状态,如果pos位置是0:表示该位置被占用了,pos位置是1:表示该位置没有被占用但是上一层的pos位置被占用了,pos位置是2:表示该位置和上一层的该位置否没有被占用。

    用数组last[]和now[]表示上一层和本层的状态(用编码器和解码器实现)如果该位置为坏点那么now[pos]=0,否则now[pos]=min(2,last[pos]+1);用DFS实现,横着放,竖着放,或者不放,最后取最后一行每个状态下的值,取最大。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 60050;
    int dp[2][maxn], cur;
    int last[15], now[15];
    int mp[155][15];
    int T, Last, lim;
    int n, m, k;
    int en_code()//编码器
    {
        int ans = 0;
        for(int i = m - 1; i >= 0; i--) ans = ans * 3 + now[i];
        return ans;
    }
    void de_code(int x)//译码器
    {
        for(int i = 0; i < m; i++)
        {
            last[i] = x % 3;
            x /= 3;
        }
    }
    void DFS(int pos, int val, int r)
    {
        if(pos == m)//本行已经处理完
        {
            int j = en_code();
            dp[cur][j] = max(dp[cur][j], dp[cur ^ 1][Last] + val);
            return ;
        }
        if(mp[r][pos])//如果当前位置是坏点,直接跳过
        {
            now[pos] = 0;
            DFS(pos + 1, val, r);
            return ;
        }
        now[pos] = min(2, last[pos] + 1);//当前行pos点的状态
        if(pos > 1 && now[pos - 1] == 2 && now[pos - 2] == 2 && now[pos] == 2)//横着放
        {
            now[pos] = now[pos - 1] = now[pos - 2] = 0;
            DFS(pos + 1, val + 1, r);
            now[pos] = now[pos - 1] = now[pos - 2] = 2;//恢复到递归前的状态
        }
        if(pos && now[pos - 1] == 2 && last[pos - 1] == 2 && last[pos] == 2)//竖着放
        {
            now[pos] = now[pos - 1] = 0;
            DFS(pos + 1, val + 1, r);
            now[pos] = now[pos - 1] = 2;//恢复到递归前的状态
        }
        DFS(pos + 1, val, r);//不放
    }
    int main ()
    {
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d%d", &n, &m, &k);
            lim = 1;
            cur = 0;
            for(int i = 1; i <= m; i++) lim *= 3;
            memset(mp, 0, sizeof(mp));
            for(int i = 1; i <= k; i ++)
            {
                int x, y;
                scanf("%d%d", &x, &y);
                y--;
                mp[x][y] = 1;
            }
            memset(dp, -1, sizeof(dp));
            dp[0][0] = 0;
            for(int i = 1; i <= n; i++)
            {
                cur ^= 1;
                memset(dp[cur], -1, sizeof(dp[cur]));
                for(int j = 0; j <= lim - 1; j++)
                    if(dp[cur ^ 1][j] != -1)
                    {
                        Last = j;
                        de_code(j);
                        DFS(0, 0, i);
                    }
            }
            int ans = 0;
            for(int j = 0; j <= lim - 1; j++)
                ans = max(ans, dp[cur][j]);
            printf("%d
    ", ans);
        }
    }
    想的太多,做的太少。
  • 相关阅读:
    Tensorflow 2.0 学习资源
    SpagoBI 教程 Lesson 5: Creating a dashboard with BIRT and SpagoBI
    SpagoBI 教程 Lesson 4: BIRT Reports
    SpagoBI 教程 Lesson 3: Highchart Dashboards
    SpagoBI 教程 Lesson 2: OLAP with JPIVOT
    SpagoBI 教程 Lesson 1:Introduction and Installation
    Oracle system表空间满的暂定解决方法
    运算符重载_继承_多态_模版
    成员函数返回的是对象和引用的区别(转)
    String类型_static成员_动态内存分配_拷贝构造函数_const关键字_友元函数与友元类
  • 原文地址:https://www.cnblogs.com/pealicx/p/6235811.html
Copyright © 2011-2022 走看看