• poj 1185 (状压dp)


    Problem 炮兵阵地

    题目大意

      给你一张n*m的地图,一些地区是空地,一些地区是障碍。

      可以在空地上布置炮兵部队,炮兵部队的攻击范围为上下左右各两格。

      询问最多可以布置多少个炮兵部队,且互不伤害。

      0<=N <= 100 , 0<=M <= 10

    解题分析

      由于攻击范围是两格,所以用dp[i][j][k]表示做到i行,上一行的状态为j,上上行的状态为k。

      判断上下两行的状态i,j是否矛盾,直接判断 i&j 是否为0即可。

      判断同一行的状态i是否矛盾,用 i & (i>>1) 来判断是否有相邻的炮兵部队,用 i & (i>>2) 来判断是否有间隔一格的炮兵部队。

      如果直接用2^10来表示状态会存不下,则首先预处理一下每行的可行状态即可。

      Tips :  == 的优先度要比 & 高。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 int n,m;
    32 char mp[200][200];
    33 int g[200][200];
    34 int dp[101][200][200];
    35 
    36 int main(){
    37     scanf("%d%d",&n,&m);
    38     rep(i,1,n) scanf("%s",mp[i]+1);
    39     for (int i=1;i<=n;i++){
    40         for (int j=0;j<1<<m;j++)
    41         {
    42             int flag=1;
    43             rep(k,1,m)
    44                 if (j & 1<<k-1 && mp[i][k]=='H')
    45                     flag=0;
    46             if (j & j>>1) flag=0;
    47             if (j & j>>2) flag=0;
    48             if (flag) g[i][++g[i][0]]=j;
    49         }
    50     }
    51     rep(i,1,g[1][0]) dp[1][i][0]=bitcnt(g[1][i]);
    52     rep(i,1,g[2][0]) 
    53         rep(j,1,g[1][0])
    54             if (!(g[2][i] & g[1][j]))
    55                 dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+bitcnt(g[2][i]));
    56           
    57             
    58     rep(i,3,n)
    59         rep(j,1,g[i][0])
    60             rep(k,1,g[i-1][0])
    61                 rep(l,1,g[i-2][0])
    62                     if (!(g[i][j] & g[i-1][k]))
    63                     if (!(g[i][j] & g[i-2][l]))
    64                     if (!(g[i-1][k] & g[i-2][l]))
    65                         dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+bitcnt(g[i][j]));
    66     int res=0;
    67     rep(i,1,g[n][0]) res=max(res,dp[1][i][0]);
    68     rep(i,1,g[n][0])
    69         rep(j,1,g[n-1][0]) res=max(res,dp[n][i][j]);
    70     printf("%d
    ",res);
    71 }   
    View Code
  • 相关阅读:
    SVD与PCA
    Service(二):通信
    Service(一):认识service、绑定Service
    计划(四)
    Android studio 安装过程中遇到的问题
    UFLDL 教程学习笔记(四)
    opencv之dft及mat类型转换
    《第一行代码》(四)
    《第一行代码》
    计划(三)
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5789955.html
Copyright © 2020-2023  润新知