司令部的將軍們打算在n*m的網格地圖上部署他們的炮兵部隊。乙個n*m的地圖由n行m列組成,地圖的每一格可能是山地(用「h」 表示),也可能是平原(用「p」表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:
如果在地圖中的括號所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表("*"範圍)示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。
現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。
檔案的第一行包含兩個由空格分割開的正整數,分別表示n和m;
接下來的n行,每一行含有連續的m個字元(『p』或者『h』),中間沒有空格。按順序表示地圖中每一行的資料。
n≤100;m≤10。
檔案僅在第一行包含乙個整數k,表示最多能擺放的炮兵部隊的數量。
5 4phpp
pphh
pppp
phpp
phhp
6=狀壓dp的經典題目之一。
這道題和其他一些普通的題目不同的是每乙個格仔對周圍的影響範圍有兩格。
我們先預處理出每一行有可能的情況,並且用十進位制來表示集合的狀態,然後
對於每一行的每一種狀態,列舉前兩行的每一種狀態,如果狀態可以相容,那
麼這一行的累計個數就是上一行累計的炮兵個數加上當前狀態的炮兵個數。
最後得出的答案就是最後一行的各種情況中最大的一種。
#include#include#includeusing namespace std;
inline int read()
int f[105][105][105];
int a[105][105];
int cnt[105][105];
int st[105],num[105];
int n,m,ans;
char ch[15];
void st()
for(int i=1;i<=st[0];i++)
for(int j=0;j
if(st[i]&(1<
return ;
}inline void pre(int v,int temp)return ;
}int main()
a[0][0]=1;
for(int i=1;i<=a[1][0];i++)f[1][i][1]=cnt[1][i],ans=max(ans,f[1][i][1]);
for(int i=2;i<=n;i++)
for(int j=1;j<=a[i][0];j++)
for(int k=1;k<=a[i-1][0];k++)
if(!(a[i][j]&a[i-1][k]))
for(int t=1;t<=a[i-2][0];t++)
if(!(a[i][j]&a[i-2][t])&&!(a[i-1][k]&a[i-2][t]))
cout<
return 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 炮兵陣地
題目描述 司令部的將軍們打算在nm的網格地圖上部署他們的炮兵部隊。乙個nm的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖...