POJ 1185 炮兵陣地(狀態壓縮dp)

2021-08-04 04:24:01 字數 2117 閱讀 9042

炮兵陣地

time limit:2000ms

memory limit:65536k

total submissions:28210

accepted:10914

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

dp好難啊~~

第一次一天的進度這麼慢……dp果然學得很不好……

這題的話還是很明顯的狀態壓縮dp的,因為改好總共最多只有10列,故每一行只需要用乙個10位的二進位制數字表示是否放了炮兵即可。但是此題的關鍵不是這個,此題炮兵的打擊範圍是兩格,這就意味者,第i行的狀態與第i-1行和第i-2行都有關。如此一來,按照正常的dp方式,轉移方程為:dp[i][j][k]=max(dp[i-1][k][l])+p[j]。其中dp[i][j][k]表示第i行狀態j且第i-1行狀態為k時的炮兵最多數量,p[j]表示j狀態下的炮兵數量。可以看出光列舉三個狀態j、k和l的複雜度就已經到了o(2^3n),即2^30顯然會超時。

但是實際我們發現,真正可行的方案並沒有我們列舉的那麼多。因為炮兵前後左右都有影響,而且還有本身地形的限制,所以狀態數非常有限,沒有必要用列舉浪費時間。我們考慮可以每次進入時,先預處理第i行的狀態,並把狀態儲存。可以證明,每一行的狀態數不超過60種,具體的預處理方法就是用乙個dfs,並把狀態和相應的p陣列存下。有了這些,我們就直接可以選擇預處理的狀態來進行dp。為了節省空間,還用了滾動陣列。dp方程:dp1[j][k]=max(dp2[k][l])+p[j]。看似沒有多大的區別,其實整個表示都不同,dp[j][k]表示到了第i行選取第j個狀態且第i-1行為第k個狀態的炮兵最多數目,p[j]表示第j個狀態的炮兵增加數目。這裡並不直接列舉,而是用預存下來的狀態。總的複雜度為o(n*k^3)其中k大約為60,再加上2s的時間,2000w的資料量差不多剛好能過,實際效果更好。具體**如下:

#include#include#include#include#include#include#include#include#include#define ll long long

#define n 111

using namespace std;

int dp1[n][n],dp2[n][n],p[n],n,m;

vectornow,last,lastlast;

bool mp[n][n];

void dfs(int i,int j,int sta,int val) //預處理狀態

if (mp[i][j]) dfs(i,j+3,sta|(1<

poj1185 炮兵陣地(狀態壓縮)

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

poj 1185炮兵陣地(狀態壓縮)

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

POJ1185 炮兵陣地 狀態壓縮DP

感覺和3254很像,不過這次的間隔變成兩格,當前行的狀態與上兩行的狀態有關。狀態轉移方程 dp k q i max dp k q i dp q j i num k num k 表示狀態k的炮兵數量 dp k q i 表示當前第i行為狀態k上一行的狀態為q的炮兵數量總數。炮兵陣地 time limit...