poj1185 炮兵陣地 經典狀態壓縮dp

2021-08-22 07:16:25 字數 1521 閱讀 8176

狀態dp,用二進位制位來表示當前的乙個狀態值,只不過比上乙個稍微複雜了一點,需要用三維的陣列來儲存當前state。

題目:在乙個n*m的矩陣上布置炮兵部隊,只有平原可以布置,然後每個炮兵部隊都有乙個攻擊範圍,它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。

問:如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊?

由於是求的最多能放置的炮兵個數,就是求某乙個狀態下,它對應的炮兵個數最多,所以就想到dp方程肯定是那種dp[i+1]=max的形式,又考慮到每一行的狀態只和前兩行有關係,所以考慮用dp來做,下面考慮如何用二進位制位來表示乙個狀態及轉移方程。

由於當前行和前兩行有關係,所以得用3維矩陣來儲存乙個狀態下最多的炮兵個數,用dp[i][now][last]表示當前第i行狀態,前一行狀態的最大炮兵數。

轉移方程為dp[i][now][last]=max,這樣求到最後一行之後,答案就是最後一行所有狀態中最大的那個。程式初始化的時候需要對第一行進行預處理,設定dp[0][st][0]=st合法&st中1的個數。這樣進行下面的計算的時候,由於0狀態肯定是和所有狀態相容的,所以就不會影響計算結果。

**如下:

#include#include#includeusing namespace std;

int dt[105][12];

int dp[101][64][64];//dp[i][now][last]表示填寫第i行的時候,i的狀態,和i-1行的狀態

int m,n;

int num[65];

int shumu;

int biti[11];

bool phf(int i)//用來遍歷一行所有的可放置情況

for(int i=1;i<=9;i++)

for(int j=i+1;j<=10;j++)

return 1;

}bool fhdx(int i,int h)//判斷某行的可行解與地形是否ok

//先遍歷一行所有的可以放置的情況

int ke[64];

int xu=1;

for(int i=0;i<=(pow(2,m)-1);i++)

}//計算發現合法的一行有60種放的方法

xu--;

if(n==1)//如果只有一行,需要特判

//獲得初始條件dp[2]開頭的資料

for(int i=1;i<=xu;i++)

for(int j=1;j<=xu;j++)

}//開始狀態轉移

for(int i=3;i<=n;i++)}}

//找到最多的炮台數目,並輸出

int maxn=0;

for(int i=1;i<=xu;i++)

for(int j=1;j<=xu;j++)

cout

}

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...