POJ 1185 炮兵陣地

2021-10-07 16:46:50 字數 3174 閱讀 1727

題目鏈結

司令部的將軍們打算在 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...