失踪百景

惯性生存者

导航

POJ 3311 Hie with the Pie (状压DP)

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;
}

 

posted on 2016-04-25 18:44  失踪百景  阅读(166)  评论(0编辑  收藏  举报