題目鏈結
司令部的將軍們打算在 n∗m
n*mn∗
m 的網格地圖上部署他們的炮兵部隊。乙個 n∗m
n*mn∗
m 的地圖由n行m列組成,地圖的每一格可能是山地(用"h" 表示),也可能是平原(用"p"表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:
如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。
現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。
第一行包含兩個由空格分割開的正整數,分別表示n和m;
接下來的n行,每一行含有連續的m個字元(『p』或者』h』),中間沒有空格。按順序表示地圖中每一行的資料。n <= 100;m <= 10。
僅一行,包含乙個整數k,表示最多能擺放的炮兵部隊的數量。
5 4
phpp
pphh
pppp
phpp
phhp
6
非常經典的狀壓 dp,和 hduoj 1565 這道題方法類似,只不過方格取數是不能相鄰,這道題條件更複雜一些,要隔兩格~
狀壓 dp 要暴力算出每行所有可能的取值情況,即 [0,
2m)[0,2^m)
[0,2m)
,又要錯兩格,也即可能取值情況的二進位制中的所有 1
11 之間的間隔必須大於 2
22,這可以用 ((i
&(i>
>2)
)=0)
&&((
i&(i
>
>1)
)=0)
((i\&(i>>2))=0)\&\&((i\&(i>>1))=0)
((i&(i
>
>2)
)=0)
&&((
i&(i
>
>1)
)=0)
來判斷,通過上面的列舉和篩除就可以得到每一行的所有可能情況,下面考慮動態規劃~
因為對第 i
ii 行受第 i−1
i-1i−
1 行和第 i−2
i-2i−
2 行的影響,所以要比方格取數多一維,我們用 dp[
i][j
][k]
dp[i][j][k]
dp[i][
j][k
] 表示第 i
ii 行以 j
jj 為狀態第 i−1
i-1i−
1 行以 k
kk 為狀態時的最大炮兵數量,val
valva
l 表示第 i
ii 行的炮兵數量,即 j
jj 的二進位制中 1
11 的個數,可以用內建函式 __b
uilt
in_p
opco
unt\_\_builtin\_popcount
__buil
tin_
popc
ount
計算,則有狀態轉移方程:
d p[
i][j
][k]
=max
(dp[
i][j
][k]
,dp[
i−1]
[k][
l]+v
al),
l&k=
0,l&
j=0dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+val),l\&k=0,l\&j=0
dp[i][
j][k
]=ma
x(dp
[i][
j][k
],dp
[i−1
][k]
[l]+
val)
,l&k
=0,l
&j=0
但此時複雜度還是太高,我們繼續考慮優化,對於每一行的炮兵排布,我們可以用預處理成二進位制,即有炮兵視作 1
11,否則為 0
00,存入陣列 opop
op,那麼對於每一行狀態的選擇 j
jj,必須要滿足 op[
i]&j
≠0op[i]\&j\neq 0
op[i]&
j=
0,這樣又篩除一部分進而能降低複雜度,對應的,狀態轉移時要滿足:
o p[
i]&j
≠0op[i]\&j\neq 0
op[i]&
j=0op
[i−1
]&k≠
0op[i-1]\&k\neq 0
op[i−1
]&k
=0op[
i−2]
&l≠0
op[i-2]\&l\neq 0
op[i−2
]&l
=0
在狀態轉移時可以不用考慮下標為負的情況,因為在c的語法裡並不算錯,ac**如下:
#include
#include
using
namespace std;
char s[
105][1
<<10]
;int dp[
105]
[100][
100]
;int n,m,cnt,ans,num[
1<<10]
,op[
1<<10]
;int
main()
ans=
max(dp[i]
[j][k]
,ans);}
}}printf
("%d\n"
,ans)
;}
poj 1185 炮兵陣地
題目鏈結 題意 在n m的網格地圖上部署炮兵部隊。地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中...
POJ 1185 炮兵陣地
include include include include include include include include include include include include include include define sz v int v size define rep i,n ...
POJ 1185 炮兵陣地
狀態壓縮專題第一題,自己想了很久,最終還是以別人的 為模板寫的。dp共三維,一維是行數,一維是前一行狀態,一維是前第二行狀態。ps 直接開三維太大,用s陣列記錄下所有可能出現的情況,大大減少時間和空間。include include include includeusing namespace st...