1. 程式人生 > >poj 1185 狀態壓縮

poj 1185 狀態壓縮

組成 earch tac queue int -1 can name 整數

炮兵陣地
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 27926 Accepted: 10805

Description

司令部的將軍們打算在N*M的網格地圖上部署他們的炮兵部隊。一個N*M的地圖由N行M列組成,地圖的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:
技術分享

如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。
現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。

Input

第一行包含兩個由空格分割開的正整數,分別表示N和M;
接下來的N行,每一行含有連續的M個字符(‘P‘或者‘H‘),中間沒有空格。按順序表示地圖中每一行的數據。N <= 100;M <= 10。

Output

僅一行,包含一個整數K,表示最多能擺放的炮兵部隊的數量。

Sample Input

5 4
PHPP
PPHH
PPPP
PHPP
PHHP

Sample Output

6

Source

Noi 01 題意:給你一個m*n的矩陣 每一塊 P代表平原 可以安放炮臺 現在按照要求部署炮臺 任意兩個炮臺之間的距離應當大於2 問最多能夠安放多少個炮臺 題解:dp[i][j][l] 代表第i行部署狀態為l 第i-1行部署狀態位j的情況下的答案
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<map>
 7
#include<queue> 8 #include<stack> 9 #include<vector> 10 #include<set> 11 #define ll __int64 12 #define mod 100000000 13 using namespace std; 14 int n,m; 15 int a[70]; 16 int b[110]; 17 int dp[110][70][70]; 18 char w[105][105]; 19 int cnt=0; 20 int bit[70]; 21 int fin (int x) 22 { 23 int jishu=0; 24 while(x>0) 25 { 26 if(x%2==1) 27 jishu++; 28 x/=2; 29 } 30 return jishu; 31 } 32 bool check(int x)//判斷每一行可行的部署方案 33 { 34 if(x&(x/2)) return false; 35 if(x&(x/4)) return false; 36 return true; 37 } 38 bool fun(int x,int k)//判斷是否滿足平原的要求 39 { 40 if(x&b[k]) return false; 41 else return true; 42 } 43 int main() 44 { 45 scanf("%d %d",&m,&n); 46 char exm; 47 cnt=0; 48 for(int i=0; i<(1<<n); i++){ 49 if(check(i)){ 50 a[++cnt]=i; 51 bit[cnt]=fin(i); 52 } 53 } 54 memset(b,0,sizeof(b)); 55 for(int i=1; i<=m; i++) 56 scanf("%s",w[i]+1); 57 for(int i=1; i<=m; i++) 58 for(int j=1; j<=n; j++) 59 if(w[i][j]==H) 60 b[i]+=(1<<(n-j)); 61 memset(dp,-1,sizeof(dp)); 62 for(int i=1; i<=cnt; i++){ 63 if(fun(a[i],1)) 64 dp[1][1][i]=bit[i]; 65 } 66 67 for(int i=2; i<=m; i++){ 68 for(int k=1; k<=cnt; k++){ 69 if(!fun(a[k],i)) continue; 70 for(int j=1; j<=cnt; j++){ 71 if(a[k]&a[j]) continue; 72 for(int l=1;l<=cnt;l++){ 73 if(a[k]&a[l]) continue; 74 if(dp[i-1][j][l]==-1) continue; 75 dp[i][l][k]=max(dp[i][l][k],dp[i-1][j][l]+bit[k]); 76 } 77 } 78 } 79 } 80 int ans=0; 81 for(int i=1;i<=m;i++) 82 for(int j=1;j<=cnt;j++) 83 for(int l=1;l<=cnt;l++) 84 ans=max(ans,dp[i][j][l]); 85 printf("%d\n",ans); 86 return 0; 87 }

poj 1185 狀態壓縮