Description:
伊朗伊斯兰革命卫队(某恐怖组织)正在策划一起刺杀行动,他们的目标是沙特驻美大使朱拜尔。他们来到了沙特驻美使馆,准备完成此次刺杀,要进入使馆首先必须通过使馆前的防御迷阵。
迷阵一个由n*m个相同的小房间组成,每个房间与相邻四个房间之间有门可通行。在第n行的m个房间里有m个机关,这些机关必须全部被打开才可以进入大使馆。而第1行的m个房间有m扇向外开的门,是迷阵的入口。除了第1行和第n行的房间外,每个房间都被使馆的安保人员安装了激光杀伤装置,将会对进入房间的人造成一定的伤害。第i行第j列造成的伤害值为p[i][j](第1行和第n行的p值全部为0)。
现在伊斯兰革命卫队打算以最小伤害代价进入迷阵,打开全部机关,显然,他们可以选择任意多的人从任意的门进入,但必须到达第n行的每个房间。一个士兵受到的伤害值为他到达某个机关的路径上所有房间的伤害值中的最大值,整个部队受到的伤害值为所有士兵的伤害值中的最大值。现在,这个恐怖组织掌握了迷阵的情况,他们需要提前知道怎么安排士兵的行进路线可以使得整个部队的伤害值最小。
Input
第一行有两个整数n,m,表示迷阵的大小。
接下来有n行,每行m个数,第i行第j列的数表示p[i][j]。
Output
输出一个数,表示最小伤害代价。
Solution
传说中的二分神器
我们来看看样例数据。
Tables | 1列 | 2列 |
---|---|---|
1行 | 0 | 0 |
2行 | 3 | 5 |
3行 | 2 | 4 |
4行 | 0 | 0 |
由此看出,我们只需要走到第
n
行任意位置,即可走完所有且不花费。(废话)
由此,我们可以二分答案,Bfs检验(
Program
var
n,m,i,j:longint;
data:array [1..1000001,1..2] of longint;
p:array [0..1001,0..1001] of longint;
move:array [1..4,1..2] of longint=((0,1),(1,0),(-1,0),(0,-1));
function Bfs(x:longint):boolean;
var
bj:array [1..1000,1..1000] of boolean;
i,j,k:longint;
begin
fillchar(bj,sizeof(bj),true);
for i:=1 to m do
begin
data[i,1]:=1;
data[i,2]:=i;
bj[1,i]:=false;
end;
i:=0;
j:=m;
while i<j do
begin
inc(i);
for k:=1 to 4 do
if (p[data[i,1]+move[k,1],data[i,2]+move[k,2]]<=x) and (bj[data[i,1]+move[k,1],data[i,2]+move[k,2]]) then
begin
if data[i,1]+move[k,1]=n then
exit(true);
inc(j);
data[j,1]:=data[i,1]+move[k,1];
data[j,2]:=data[i,2]+move[k,2];
bj[data[i,1]+move[k,1],data[i,2]+move[k,2]]:=false;
end;
end;
exit(false);
end;
function GA(l,r:longint):longint;
var
mid:longint;
begin
if l>=r then
exit(l);
mid:=(l+r) shr 1;
if Bfs(mid) then
exit(GA(l,mid))
else
exit(GA(mid+1,r));
end;
begin
readln(n,m);
fillchar(p,sizeof(p),$7f);
for i:=1 to n do
begin
for j:=1 to m do
read(p[i,j]);
readln;
end;
writeln(GA(1,1000));
close(input);
close(output);
end.