码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3311 Hie with the Pie (状压DP)

时间:2016-04-25 19:37:51      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:

dp[i][j][k] i代表此层用的状态序号 j上一层用的状态序号 k是层数&1(滚动数组)

标准流程 先预处理出所有合法数据存在status里 然后独立处理第一层 然后根据前一层的max推下一层

由于最多只有60多种状态 所以这其实就是个大暴力 其实还不慢

关于为什么要反义输入地图 因为我懒得写一个地图匹配状态函数了 所以直接让地图反义匹配状态

 

应该算是比较简单的状压DP

然而我还是写残了WA了两次orz

#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

int size, status[110], num[110];
int n, m, maze[110], dp[110][110][2];

inline bool ok(int a){
    return !((a & (a >> 1)) || (a & a >> 2));
}

inline bool fit(int a, int b){
    return !(a & b);
}

void init(){
    size = 0;
    memset(num, 0, sizeof num);
    int top = 1 << m;
    for(int i = 0; i < top; ++i){
        if(ok(i)){
            status[size] = i;
            int tmp = i;
            while(tmp){
                if(tmp & 1) num[size]++;
                tmp >>= 1;
            }
            ++size;
            //cout << i << ends << num[size] << endl;
        }
    }
}


int main()
{
    while(cin >> n >> m){
        init();

        for(int i = 0; i < n; ++i){
            string tmp;
            cin >> tmp;
            for(int j = 0; j < m; ++j){
                maze[i] <<= 1;
                //地图要反义输入
                maze[i] += (tmp[j] == H);
            }
            //cout << maze[i] << endl;
        }

        memset(dp, 0, sizeof dp);
        for(int i = 0; i < size; ++i){
            if(fit(status[i], maze[0])){
                dp[i][0][0] = num[i];
                //cout << status[i] << ends << num[i] << endl;
            }
        }
        for(int i = 1; i < n; ++i){
            for(int j = 0; j < size; ++j){
                if(fit(maze[i], status[j])){
                    for(int k = 0; k < size; ++k){
                        if(fit(status[j], status[k])){
                            int maxx = 0;
                            for(int l = 0; l < size; ++l){
                                if(fit(status[j], status[l])){
                                    maxx = max(maxx, dp[k][l][!(i&1)]);
                                }
                            }
                            dp[j][k][i&1] = max(dp[j][k][i&1], maxx + num[j]);
                        }
                    }
                }
            }
        }

        int ans = 0;
        for(int i = 0; i < size; ++i){
            for(int j = 0; j < size; ++j){
                ans = max(ans, dp[i][j][!(n&1)]);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

 

POJ 3311 Hie with the Pie (状压DP)

标签:

原文地址:http://www.cnblogs.com/quasar/p/5432279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!