zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    sqlserver获取当前id的前一条数据和后一条数据
    C#实现测量程序运行时间及cpu使用时间
    类库dll引用不成功问题
    合并相同字段
    Android之来历
    XML and JSON 验证
    特殊符号
    git 使用
    格式化字符串:金额
    grunt + sass 使用记录
  • 原文地址:https://www.cnblogs.com/quasar/p/5432279.html
Copyright © 2011-2022 走看看