PKU 1185 炮兵陣地 狀壓DP

2022-06-22 21:30:14 字數 2547 閱讀 7502

題目鏈結

司令部的將軍們打算在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 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰...