Description
給出一個H的行和W列的網格。第i行第j列的狀態是由一個字母的A[i][j]表示,如下:
“.” 此格爲空。
“o” 此格包含一個機器人。
“E” 此格包含一個出口,保證出口在整個網格中有且只有一個
每次可以選擇上,下,左,右之一的方向,將所有剩餘的機器人向這個方向移動一個格子,如果一個機器人被移出了網格,那麼這個機器人會爆炸,並立即消失。如果一個機器人移動到出口所在的格子,機器人將獲救,並消失,最多有多少機器人獲救。
Solution
我們設
紅色區域已經沒有機器人了,這是由於移出邊界爆炸或者在這之前獲救,而黃色區域的機器人已經獲救了(顯然如果沒有獲救,那麼一定不優,因爲犧牲了紅色區域之後,黃色區域是一定能到達出口的),那麼我們可以通過增加可行範圍,即增加黃色區域的邊界,進而對答案不斷地推進。假設我們在最上一行犧牲掉一行,那麼在下一行就一定能夠選到一行。
當我們犧牲掉上一行時,下面紫色的一行就能被必定選上(正確性已證),同樣推及四個方向就能弄出四條遞推式,遞推式其實不太難,在這裏就不詳細寫出來了。由於
Code
var
map:array[0..101,0..101] of char;
f:array[0..1,0..101,0..101,0..101] of longint;
x,y:array[0..101,0..101] of longint;
s:array[1..4] of longint;
n,m,i,j,l,r,u,d,ex,ey,ans,z:longint;
function max(x,y:longint):longint;
begin
if x>y then exit(x);exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x);exit(y);
end;
function getl(h1,h2,l1:longint):longint;
begin
if ey-l-1<=r then exit(0);
h1:=min(h1,n-u);h2:=max(h2,d);
exit(x[h1][l1]-x[h2][l1]);
end;
function getr(h1,h2,l1:longint):longint;
begin
if m-l<=r+ey then exit(0);
h1:=min(h1,n-u);h2:=max(h2,d);
exit(x[h1][l1]-x[h2][l1]);
end;
function getu(h1,l1,l2:longint):longint;
begin
if ex-u-1<=d then exit(0);
l1:=min(l1,m-l);l2:=max(l2,r);
exit(y[h1][l1]-y[h1][l2]);
end;
function getd(h1,l1,l2:longint):longint;
begin
if n-u<=d+ex then exit(0);
l1:=min(l1,m-l);l2:=max(l2,r);
exit(y[h1][l1]-y[h1][l2]);
end;
begin
readln(n,m);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(map[i,j]);
x[i,j]:=x[i-1,j];y[i,j]:=y[i,j-1];
if map[i,j]='E' then
begin
ex:=i;ey:=j;
s[1]:=i-1;s[2]:=j-1;s[3]:=n-i;s[4]:=m-j;
end
else if map[i,j]='o' then
begin
inc(x[i,j]);inc(y[i,j]);
end;
end;
readln;
end;
for l:=0 to s[2] do
begin
z:=1-z;
fillchar(f[1-z],sizeof(f[1-z]),0);
for r:=0 to s[4] do
for u:=0 to s[1] do
for d:=0 to s[3] do
begin
f[z,r,u,d+1]:=max(f[z,r,u,d+1],f[z,r,u,d]+getd(ex+d+1,ey+r,ey-l-1));
f[z,r+1,u,d]:=max(f[z,r+1,u,d],f[z,r,u,d]+getr(ex+d,ex-u-1,ey+r+1));
f[z,r,u+1,d]:=max(f[z,r,u+1,d],f[z,r,u,d]+getu(ex-u-1,ey+r,ey-l-1));
f[1-z,r,u,d]:=max(f[1-z,r,u,d],f[z,r,u,d]+getl(ex+d,ex-u-1,ey-l-1));
ans:=max(ans,f[z,r,u,d]);
end;
end;
writeln(ans);
end.