码迷,mamicode.com
首页 > 其他好文 > 详细

poj 1185 (状压dp)

时间:2016-08-20 11:27:04      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

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\n",res);
71 }   
View Code

 

poj 1185 (状压dp)

标签:

原文地址:http://www.cnblogs.com/rpSebastian/p/5789955.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!