E departe d a fi solutie oficiala dar ia testele
program p1130101;
const MAX_WORD = 65530;
var inp,out: text;
a: array[1..100,1..100] of byte;
d: array[1..100,1..100] of word;
m,n,i,j: byte;
min2,j_min: word;
procedure mat_cob; { transforma matricea in mat coborari }
var i,j: byte;
begin
for i:=1 to m-1 do
for j:=1 to n do
d[i,j] := a[i+1,j] + a[i,j];
d[1,1] := MAX_WORD;
end;
function get_l_min(i: byte): word;
var j: byte;
min: word;
begin
min := MAX_WORD;
min2 := MAX_WORD;
for j:=1 to n do
if d[i,j] < min then
begin
{ min2 := min; } { min2 NU este intotdeauna det corect }
{ greseala FATALA :((( }
min := d[i,j];
j_min:= j;
end;
for j:=1 to n do { varianta corecta }
if (d[i,j] < min2) and (j <> j_min) then
min2 := d[i,j]; { /varianta corecta :((( }
get_l_min := min;
end;
procedure get_min;
var i,j: byte;
l_min : word;
begin
for i:=2 to m-1 do
begin
l_min := get_l_min(i-1);
for j:=1 to n do
if j <> j_min then
d[i,j] := d[i,j] + l_min
else
d[i,j] := d[i,j] + min2;
end;
d[m-1,n] := MAX_WORD;
end;
begin
assign(inp, 'lacusta.in');
reset(inp);
assign(out, 'lacusta.out');
rewrite(out);
readln(inp, m,n);
for i:=1 to m do
begin
for j:=1 to n do
read(inp,a[i,j]);
readln(inp);
end;
mat_cob;
get_min;
{ writeln('*********************************');
for i:=1 to m do
begin
for j:=1 to n do
write(d[i,j]:6);
writeln;
end; }
if (m = 0) or (n = 0) then
writeln(out,0)
else
writeln(out,get_l_min(m-1)+a[1,1]+a[m,n]);
close(inp);
close(out);
end.
Fara commentarii (explicatii) ,exact ca o solutie oficiala
d este a doua matrice in d[i,j] tin initial suma(a[i,j]+a[i+1,j]) adica costul coborarii d la a[i,j] la a[i+1,j] ;
Shi dupa aia d[i,j] -> d[i,j] + min(d[i-1,1..n])
drumul minim il gasesti ca fiind min(d[m-1,1..n]) (adica minimul de pe ultima linie)
La solutia finala adaugi primul shi ultimul element al matricei (prin care oricum treci)
O PD BANALA care merge in O(N*M);
Si p care am luat 20 p
Sper ca te-a ajutat !
P.S.: daca ai nevoie de o varianta C sa zici !