zoukankan      html  css  js  c++  java
  • 状态压缩动态规划 -- 炮兵阵地


    司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队,一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),例如以下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不可以部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所看到的:


    假设在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它可以攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其他白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。如今,将军们规划怎样部署炮兵部队,在防止误伤的前提下(保证不论什么两支炮兵部队之间不能互相攻击,即不论什么一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多可以摆放多少我军的炮兵部队。


    题目链接:http://poj.org/problem?id=1185


    #include <iostream>
    #include <cstring>
    using namespace std;
    #define MAX_SIZE 110
    int graph[MAX_SIZE];
    int DP[MAX_SIZE][MAX_SIZE][MAX_SIZE];
    // DP[raw][i][j] : 在第 raw 行状态为 i, 第 raw - 1 行状态为 j 的情况
    int pointer, state_stack[MAX_SIZE], ones_num[MAX_SIZE];
    
    // 推断该状态左右相邻两个单位是否有炮兵冲突
    bool isReasonableState( int state ){
        if( state & ( state << 1 ) )
            return false;
        if( state & ( state << 2 ) )
            return false;
        return true;
    }
    
    // 计算比特位里的 1 的个数
    int getOnesNum( int state ){
        int num = 0;
        while( state > 0 ){
            if( state & 1 )
                num++;
            state >>= 1;
        }
        return num;
    }
    
    // 预处理,统计下全部“行”摆放炮兵的合法状态
    void pretreatment( int cols ){
        int max_state = ( 1 << cols ) - 1;
        for( int state = 0; state <= max_state; ++state ){
            if( isReasonableState( state ) ){
                state_stack[pointer] = state;
                ones_num[pointer]    = getOnesNum( state );
                pointer++;
            }
        }
    }
    
    int main(){
        memset( DP, -1, sizeof( DP ) );
        memset( graph, 0, sizeof( graph ) );
        pointer = 0;
    
        int raws, cols;
        cin >> raws >> cols;
        pretreatment( cols );
    
        for( int raw = 0; raw < raws; ++raw ){
            for( int col = 0; col < cols; ++col ){
                char c;
                cin >> c;
                if( c == 'H' )
                    graph[raw] |= ( 1 << col );
            }
        }
    
        for( int p = 0; p < pointer; ++p )
            if( !( state_stack[p] & graph[0] ) )
                DP[0][p][0] = ones_num[p];
    
        for( int raw = 1; raw < raws; ++raw ){
            for( int raw_p = 0; raw_p < pointer; ++raw_p ){
                if( state_stack[raw_p] & graph[raw] )
                    continue;
                for( int raw_p_ = 0; raw_p_ < pointer; ++raw_p_  ){
                    if( state_stack[raw_p] & state_stack[raw_p_] )
                        continue;
                    for( int raw_p__ = 0; raw_p__ < pointer; ++raw_p__ ){
                        if( state_stack[raw_p] & state_stack[raw_p__] )
                            continue;
                        if( DP[raw - 1][raw_p_][raw_p__] == -1 )
                            continue;
                        DP[raw][raw_p][raw_p_] = max( DP[raw][raw_p][raw_p_],
                                                DP[raw - 1][raw_p_][raw_p__] + ones_num[raw_p] );
                    }
                }
            }
        }
        int ans = 0;
        for( int raw_p = 0; raw_p < pointer; ++raw_p )
            for( int raw_p_ = 0; raw_p_ < pointer; ++raw_p_ )
                ans = max( ans, DP[raws - 1][raw_p][raw_p_] );
    
        cout << ans << endl;
        return 0;
    }
    


  • 相关阅读:
    Python: Lambda Functions
    转:解决Python2.7的UnicodeEncodeError: ‘ascii’ codec can’t encode异常错误
    Python 读取json文件
    (转)The windows boot configuration data file dose not contain a valid OS entry
    Python+PyQt5:停靠组件QDockWidget的实现
    Python零碎(一)
    (转)有关thread线程
    (转)有关Queue队列
    (转)Python中的random模块
    (转)python中的参数:*args和**kwargs
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4076957.html
Copyright © 2011-2022 走看看