POJ1185 炮兵陣地 狀壓dp

2021-07-10 16:12:13 字數 1874 閱讀 9131

司令部的將軍們打算在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
這道題也是一道非常經典的狀態壓縮dp,與hdu4539非常類似。題目大意是在一塊n*m的地上,p表示可以放置大炮,h表示障礙。乙個大炮能攻擊其前後左右距離為2的位置(包括自己的位置),求在不會互相攻擊的前提下最多放置的大炮數量。

具體看** **注釋有解釋。

#include #include #include #include #include #include #include #define max(a,b) (a)>(b)?(a):(b)

using namespace std;

typedef long long ll;

int n,m,k;

int sum[105];//sum[i]表示在第i狀態下的大炮放置數量

int dp[105][60][60];//dp[i][j][k]表示的是在i行j狀態,i-1行k狀態的值

//60這個數字的意思是在一行中,所可能出現的狀態個數不多於60個

int mp[105];//mp[i]表示第i行的輸入狀態

int state[60];//state[i]表示第i個狀態的表示(二進位制轉化十進位制儲存)

bool ok(int x)//去掉橫向干擾的

int get1(int x)//1的個數

return ret;

}void find()//無障礙情況下找出所有合法狀態

k=0;

find();

dp();

int ans=0;

for(int i=0; i

for(int j=0; j

ans=max(ans,dp[n-1][i][j]);

printf("%d\n",ans);

}return 0;

}//再著重解釋一下dp[105][60][60]的60

//因為其攻擊範圍的原因,一行最多10格,最多放置4個。

//放置4個情況1種,3個情況(4+3+2+1)+(3+2+1)+(2+1)+1=20,

//放置2個情況為7+6+5+4+3+2+1=28,放置1個為10中,放置0個為1種,其和為60種。

//所以為了減少空間消耗,60種即可。

POJ1185(炮兵陣地) 狀壓DP

每一行的狀態是取決於上一行和上上一行的,所以每次更新的時候需要記錄當前行的狀態和下一行的狀態,然後再進行遞推。不過估算了一下複雜度是10的11次方,嚇得我都沒敢寫啊!看了一下別人的部落格,居然真有這樣寫過的,於是就自己實現一邊啦 最後看了以下討論版,處理一下複雜度可以降低的,最後貼討論版 思路 令p...

POJ 1185 炮兵陣地 狀壓DP

炮兵陣地 time limit 2000ms memory limit 65536k total submissions 25954 accepted 10004 description 司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地...

POJ 1185 炮兵陣地 狀壓DP

炮兵陣地 time limit 2000ms memory limit 65536k total submissions 26638 accepted 10267 description 司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地...