司令部的將軍們打算在n*m的網格地圖上部署他們的炮兵部隊。乙個n*m的地圖由n行m列組成,地圖的每一格可能是山地(用「h」 表示),也可能是平原(用「p」表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:
如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。 現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。
第一行包含兩個由空格分割開的正整數,分別表示n和m;
接下來的n行,每一行含有連續的m個字元(『p』或者『h』),中間沒有空格。按順序表示地圖中每一行的資料。n≤100;m≤10。
僅一行,包含乙個整數k,表示最多能擺放的炮兵部隊的數量。
輸入 #1
5 4輸出 #1phpp
pphh
pppp
phpp
phhp
6這道題是一道狀壓 dp 的特別毒瘤的基礎題(雖然我打了整整乙個早上),但是因為每乙個炮兵都會影響到之後的兩行的放置,所以用狀壓去壓兩行,按行處理每一行的情況即可。每一行放置的時候也很簡單,只需考慮這個位置前兩行有沒有放置炮兵以及這個位置是不是山丘即可。【解題思路】
那麼首先,dp 方程可以很快推出來,dp[l][s][i]表示當前狀態是 s,上一行的狀態是 l,當前考慮到了第 i 行:
dp[l][s][i]=max(dp[l][s][i],dp[fl][l][i-1]+sum[s]); 這裡 fl 表示上上行的狀態,sum[s] 表示當前狀態 s 裡面包含幾個 1。
那麼有了這個 dp 方程後,就可以愉快的遞推了,不過這道題有幾個細節需要注意一下:
1.判斷每個位置是不是山丘
這個很好解決,只要把每一行的輸入都轉成乙個二進位制數(平原是 0,山丘是1),然後直接跟待判斷的狀態做一次位運算即可,就是 s&a[i],如果位運算結果不是零,說明有些位置放在了山丘上,也就是說當前狀態不合法。
2.判斷每個狀態有沒有兩個炮兵左右距離在兩格之內
這個需要動腦想一下,我們發現乙個神奇的結論,如果把表示當前狀態的二進位制數字運算左移一位,那麼用這個結果與原狀態做一次位運算與操作,如果結果不是 0,那麼就一定存在兩個炮兵左右距離在一格之內。同理,左移兩位就可以判斷左右距離在兩格之內。這個過程也就是 s&(s<<1),s&(s<<2)。
3.判斷每一列之前兩行有沒有炮兵
這個就直接用當前狀態分別與之前的兩行即可,就是 s&l,s&fl,如果與操作結果不為零,說明有若干列前兩行有炮兵,也就是說當前狀態不合法。
最後說一句,一定要用滾動陣列(因為只用到每一行和前兩行,所以只用滾動三行),否則會 mle 0 (我當初就是這麼慘)。。。
好了細節都說完了,下面就是具體的**實現了:
【code】
1 #include2using
namespace
std;
3int n,m,ans,dp[(1
<<10)][(1
<<10)][3]/*
滾動陣列
*/,a[105],sum[(1
<<10
)];4
charx;5
int getsum(int s) //
當前狀態 s 裡面包含幾個 169
return
tot;10}
11int
main()
1238}39
}40for(int l=0;l
41for(int s=0;s
42 ans=max(ans,dp[l][s][(n-1)%3]); //
結束狀態可以是最後一行的任何狀態
43 cout<
44return
0;
NOI 2001 炮兵陣地
分析 本來想的和周偉nei胖子差不多 但是感覺時間會炸,於是又苟且看了講解 發現胖子果然用會炸的方法 但是畢竟十幾年前的題了 資料略弱 dp i j k 表示前i行中,第i行狀態為j,第i 1行狀態為k時炮兵的最多數量 狀態均為01的二進位制串 方程很好寫 dp i j k max dp i j k...
NOI2001 炮兵陣地
司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的括...
NOI2001 炮兵陣地
司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 如果在地圖中的括號所標識的平原上部署一支炮兵部隊,則圖中的黑色的網...