這道題真的毒瘤…
首先觀察到列的範圍很小,這啟示我們使用狀態壓縮演算法。
我們可以預處理出所有橫排不互相攻擊的數字,顯然這些數只有一百來個。用b陣列儲存。
我們觀察到一行是否可以防止炮兵和上兩行來決定,我們設f[i
][j]
[k]f[i][j][k]
f[i][j
][k]
表示第i
ii行的狀態為b
jb_j
bj,第i−1
i-1i−
1行狀態為b
kb_k
bk可以放置的最多炮兵。
因此我們設令乙個狀態為l,有乙個顯然的狀態轉移方程是:f[i
][j]
[k]=
max(
f[i]
[j][
k],f
[i−1
][k]
[l]+
coun
t(j)
)f[i][j][k]=max(f[i][j][k],f[i-1][k][l]+count(j))
f[i][j
][k]
=max
(f[i
][j]
[k],
f[i−
1][k
][l]
+cou
nt(j
))此時,我們需要考慮這個狀態轉移方程的限制條件:
**如下:
#include
using
namespace std;
const
int n =
200;
int n, m, ans =
0, s =0;
int a[n]
, f[n]
[n][n]
, b[n]
, c[n]
;bool
check
(int x)
;for
(int i=m-
1;i>=0;
--i)
t[i+1]
= x >> i &1;
for(
int i=
3;i<=m;
++i)
if(t[i]
+t[i-1]
+t[i-2]
>1)
return0;
return1;
}bool
valid
(int x,
int y)
bool
safe
(int x,
int y,
int z)
intcount
(int x)
intmain
(void
) a[i]
= s;
}for
(int i=
0;i<
1<
++i)if(
check
(i)) b[
++s]
= i, c[s]
=count
(i);
memset
(f,-30,
sizeof f)
; f[0]
[1][
1]=0
;for
(int i=
1;i<=n;
++i)
for(
int j=
1;j<=s;
++j)if(
valid
(b[j]
,i))
for(
int k=
1;k<=s;
++k)if(
valid
(b[k]
,i-1)&&
(b[j]
&b[k])==
0)for(
int l=
1;l<=s;
++l)if(
(b[j]
&b[l])==
0) f[i]
[j][k]
=max
(f[i]
[j][k]
,f[i-1]
[k][l]
+c[j]
), ans =
max(ans,f[i]
[j][k]);
cout << ans << endl;
return0;
}
狀態壓縮DP 炮兵陣地
炮兵陣地 time limit 2000ms memory limit 65536k total submissions 11280 accepted 4065 description 司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 ...
炮兵陣地 狀態壓縮DP
一道的經典的狀態壓縮題。司令部的將軍們打算在nm的網格地圖上部署他們的炮兵部隊。乙個nm的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所...
狀態壓縮dp 炮兵陣地
題面 司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖...