題目鏈結
司令部的將軍們打算在nm的網格地圖上部署他們的炮兵部隊。乙個nm的地圖由n行m列組成,地圖的每一格可能是山地(用"h" 表示),也可能是平原(用"p"表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:
如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。
現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。
第一行包含兩個由空格分割開的正整數,分別表示n和m;
接下來的n行,每一行含有連續的m個字元('p'或者'h'),中間沒有空格。按順序表示地圖中每一行的資料。n <= 100;m <= 10。
僅一行,包含乙個整數k,表示最多能擺放的炮兵部隊的數量。
5 4phpp
pphh
pppp
phpp
phhp
狀壓dp,可以想到當前行的狀態由前兩行轉移而來,而上一行肯定又跟上上行有關係,那麼dp陣列開三維,第一維記錄當前行數,第二維記錄當前狀態,第三維記錄上一行的狀態,但是狀態最大是1<<10,顯然陣列不夠開,而如果一行全是平原,最多能有60種布陣方法,那麼可以存乙個方法序號對於狀態的對映陣列,之後只要知道轉移式怎麼寫就行了,第一行第二行不論,第三行開始以當前行為j狀態,上一行為k狀態的轉移式子為dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][k2] + cal(index[j]));k2是列舉的上上行的狀態,index是對映陣列,cal是計算當前狀態下一行能布陣幾個炮台,就是當前狀態有幾個1之後動手寫...剛學的狀壓dp,寫完這題真的清晰了不少
#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pairpii;
#define inf 0x3f3f3f3f
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll maxn = 1e6 + 7;
const ll maxm = 1e3 + 7;
const ll mod = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int sat[105];
int dp[105][70][70]; //i所在列 j這一行的狀態 k上一行的狀態
/* 可以算出總共有60種狀態 */
int index[70];
/* 用index作為方案到狀態的對映 */
int cal(int x)
return cnt;
} /* 計算某數二進位制中的一的個數 */
int main()
}int top = 1 << m;
/* for (int i = 0; i < top; i++)
*/for (int i = 0; i < top; i++)
if (!(i & (i << 2) || i & (i << 1))) //相鄰一位||相鄰兩位有炮台
index[cnt++] = i; /* 最終cnt就是最多方案數 */
for (int i = 0; i < cnt; i++)
if ((index[i] & sat[1]) == index[i]) //義大利炮在平原了
dp[1][i][0] = cal(index[i]);
/* 2~n行列舉 */
for (int i = 2; i <= n; i++)
else
dp[i][j][k] = max(dp[i][j][k], cal(index[j]) + dp[i - 1][k][0]);}}
}int ans = 0;
for (int i = 0; i < cnt; i++)
for (int j = 0; j < cnt; j++)
ans = max(ans, dp[n][i][j]);
printf("%d\n", ans);
}return 0;
}
pku 1185 炮兵陣地 狀壓DP
題意 給出乙個n m的矩陣,矩陣的每個方格標有p h p表示可以安置大炮,h表示不能安置大炮,當大炮安置於 i,j 點時,其左右兩個單位以及上下兩個單位都在攻擊範圍,求在兩支大炮不會相互攻擊的前提下,最多能夠安置大炮的數量。思路 當前行大炮的的安置要受其前兩行的影響,所以狀態轉移方程有 dp i j...
POJ1185(炮兵陣地) 狀壓DP
每一行的狀態是取決於上一行和上上一行的,所以每次更新的時候需要記錄當前行的狀態和下一行的狀態,然後再進行遞推。不過估算了一下複雜度是10的11次方,嚇得我都沒敢寫啊!看了一下別人的部落格,居然真有這樣寫過的,於是就自己實現一邊啦 最後看了以下討論版,處理一下複雜度可以降低的,最後貼討論版 思路 令p...
POJ1185 炮兵陣地 狀壓dp
司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰...