状态压缩dp入门题 POJ 1185 炮兵阵地

  POJ 1185 炮兵阵地

  中文题,题意不再赘述。

  解法:从题目可以知道,每一行的状态只与前两行有关。已知N < 100, M <= 10。很明显的可以把M压缩,把M中的每一个位置的状态可以用0,1表示。所以M的总状态可以用长度为M的二进制转化成的十进制数表示。计算可以发现总的合法状态并不多,因为要保证同一行的两个士兵不能相互攻击到。

求合法状态的关键代码:

REP(i, (1<<m)) {
        p = i;
        if(((p << 1) & i) || ((p << 2) & i))    continue;
        num[sum] = 0;
        while(p) {num[sum] += (p&1); p >>= 1;}
        status[sum++] = i;
}

status[p] = i表示表示第p个合法的状态是i。num[i] = a,表示状态为i 时安放a个炮兵。

这些数据都处理出来以后在预处理一下当前棋盘的状态0表示P,1表示H。chess[i] = s表示第i行的状态为s。

设dp[i][j][k]表示第i行的状态为j,第i - 1行的状态为k。

dp[i][j][k] = max(dp[i-1][k][p]) + num[j];

满足 (status[j]& status[k]) == 0

((status[j] & chess[i]) == 0 && (status[k] & chess[i-1]) == 0)

((status[k] & status[p]) == 0 && (status[j] & status[p]) == 0)

对于dp[0][j][k]初始化时单独些出来。dp[0][j][k] = num[j]; (不跟原棋盘冲突的情况下)

 

ps: 状压dp,又是一个神级专题,等刷完poj训练计划一定好好搞搞!明天开始埋头猛刷poj,加油!!

 

 

posted @ 2012-05-15 22:11  AC_Von  阅读(519)  评论(0编辑  收藏  举报