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