給出n*m的地圖,有很多空地p跟山地h,炮台可以攻擊周邊:
求最多能放多少個炮台並且他們互不攻擊。
n≤100;m≤10
這題是狀壓dp的一道經典題目,
對於每行10個東東可以放就是2^10種可能,這樣轉移就會tle
所以我們發現因為任意2個炮之間距離至少為2,所以我們每行存在的可行狀態至多不超過2^5
因此我們暴力處理出每行的這些狀態以及
每個狀態存在多少個炮台即可。
然後去dp即可
設f[i,k,j]表示選到了第i行,第i行狀態為s[k],第i-1行狀態為s[j]時的最大能放數量。
推得轉移方程:
f[i,k,j]=max
l為i-2行的狀態
注意判斷第i,i-1,i-2行的狀態是否衝突
var
f:array [-5..101,0..61,0..61] of longint;
s:array [-5..101,0..61] of longint;
a:array [0..101,0..11] of char;
num,c:array [0..1025] of longint;
b:array [0..11] of longint;
ans,ans1,i,j,k,l,p,n,m:longint;
check:boolean;
function
max(aa,bb:longint):longint;
begin
if aa>bb then
exit(aa);
exit(bb);
end;
procedure
dfs(dep,now,cp:longint);
var j:longint;
begin
if c[now]<>i then
begin
c[now]:=i;
if num[now]=0
then num[now]:=cp;
inc(s[i,0]);
s[i,s[i,0]]:=now;
end;
if dep=m then
exit;
for j:=dep+1
to m do
if (a[i,j]='p') and (b[j]<>i) then
begin
b[j+1]:=i;
b[j+2]:=i;
dfs(j,now+1
shl (j-1),cp+1);
b[j+1]:=0;
b[j+2]:=0;
end;
dfs(dep+1,now,cp);
end;
begin
readln(n,m);
for i:=1
to n do
begin
for j:=1
to m do
read(a[i,j]);
dfs(0,0,0);
readln;
end;
ans:=0;
for i:=1
to s[1,0] do
f[1,i,1]:=num[s[1,i]];
s[0,0]:=1; s[0,1]:=0;
for i:=2
to n do
for j:=1
to s[i,0] do
for k:=1
to s[i-1,0] do
if s[i,j] and s[i-1,k]=0
then
for l:=1
to s[i-2,0] do
if s[i-2,l] and s[i,j]=0
then
if s[i-2,l] and s[i-1,k]=0
then
begin
f[i,j,k]:=max(f[i,j,k],f[i-1,k,l]+num[s[i,j]]);
ans:=max(ans,f[i,j,k]);
end;
writeln(ans);
end.
洛谷P2704 NOI2001 炮兵陣地
題目描述 司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在...
《洛谷P2704 NOI2001 炮兵陣地》
非常細細細的一題。首先,這資料量顯然是狀壓。dp i j k 表示 到第i行,第i行狀態為j,第i 1行狀態未k的最大方案數。我們從上向下考慮的話,每個放置的棋子會被上面兩行棋子的放置狀態所影響。所以我們每次轉移的時候需要列舉上面的兩行。這樣的話複雜度就是 n m m m。這顯然已經超了 但是正解還...
洛谷 P2704 NOI2001 炮兵陣地
司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰...