luogu2704 狀壓DP 炮兵陣地

2021-10-23 13:25:16 字數 2195 閱讀 8901

題目描述

司令部的將軍們打算在nm的網格地圖上部署他們的炮兵部隊。乙個nm的地圖由n行m列組成,地圖的每一格可能是山地(用「h」 表示),也可能是平原(用「p」表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:

如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。 現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。

輸入格式

第一行包含兩個由空格分割開的正整數,分別表示n和m;

接下來的n行,每一行含有連續的m個字元(『p』或者『h』),中間沒有空格。按順序表示地圖中每一行的資料。n≤100;m≤10。

輸出格式

僅一行,包含乙個整數k,表示最多能擺放的炮兵部隊的數量。

輸入輸出樣例

輸入 #1

5 4

phpp

pphh

pppp

phpp

phhp

輸出 #1
6
解題思路

一開始把所有可能的狀態s[]

ss[

]求出來,c[]

cc[

]記錄每個狀態有多少1(放了多少個士兵)

設f []

[][]

ff[

][]存的是最多的士兵數

f [i

][k]

[j

]f[i][k][j]

f[i][k

][j]

為第i

ii行狀態為第j

jj種狀態,第i−1

i-1i−

1行的狀態為第k

kk種狀態(i

ii,j

jj,k

kk都要列舉)

由於兩個士兵必須隔兩格,所以還要列舉i−2

i-2i−

2行的狀態編號(lll)

f[i]

[k][j]

=max

(f[i]

[k][j]

, f[i-1]

[l][k]

+ c[j]

);

上一行的狀態編號是k,上一行中的f的上一行編號是l(上兩行)

code

#include 

#include

using namespace std;

char read;

long long ans, f[

105]

[120][

120]

;int n, m, num, a[

150]

, s[

110]

, c[

110]

;int main()

}for

(int i =

0; i <(1

<; i++

)//列舉狀態

for(int i =

1; i <= num; i++

)for

(int j =

1; j <= num; j++)if

(!(a[2

]& s[j])&&

!(s[j]

& s[i]))

f[2]

[i][j]

= f[1]

[0][i]

+ c[j]

;//預處理第二行

for(int i =

3; i <= n; i++

)for

(int j =

1; j <= num; j++)}

}for

(int i =

1; i <= num; i++

)for

(int j =

1; j <= num; j++

) ans =

max(ans, f[n]

[i][j]);

printf

("%lld\n"

, ans)

;}

luogu2704 炮兵陣地 狀態壓縮DP

題目大意 乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 在每一格平原地形上最多可以布置一支炮兵部隊,能攻擊到的區域 沿橫向左右各兩格,沿縱向上下各兩格。保證任何兩支炮兵部隊之間不能互相攻擊時,最多能放置的炮兵數。n 100,n 10 動規先要確定方...

洛谷2704 狀壓dp

思路 這個狀壓確實挺強。第i行的不僅僅和i 1行有關係,還和i 2行有關係。一般的思路好像解決不了問題,咋搞?我們定義乙個陣列 dp 105 1 10 1 10 dp i t1 t2 i表示的是當前行,t1表示的是當前行的狀態,t2表示的是i 1行的狀態。假設t3表示的是i 2行的狀態,列舉i 2行...

DP 狀壓 DP 炮兵陣地

狀態壓縮動態規劃和狀態機動態規劃 未更新 大體上來說都是通過另類的方式來儲存動態規劃中的狀態。狀壓dp其實可以分為 棋盤式 和 集合類 這篇是 棋盤式 或者叫 基於聯通性 的狀壓dp的一道經典例題 炮兵陣地的部落格。炮兵陣地這道非常經典的狀態壓縮dp題目是值得學習的,可以從中學習到 棋盤式 狀壓dp...