NOIP2008传纸条
原来是一个简单的DP,当时用搜索得50分,现在做DP没清零只得60分。。 斜着划分阶段,f[i,x1,x2]第i个阶段,x1, x2是两点的横坐标,每点的横纵坐标之和与阶段有关系。根据右下角为(m,n)可判断阶段数。
program message;
var
m,n:longint;
map:array[1..50,1..50] of longint;
f:array[1..100,1..50,1..50] of longint;
i,x1,y1,x2,y2,temp:longint;
procedure init;
var
i,j:longint;
begin
readln(m,n);
for i:=1 to m do
begin
for j:=1 to n do read(map[i,j]);
readln;
end;
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
begin
init;
f[1,1,2]:=map[1,2]+map[2,1]; // 第一步需特殊处理
for i:=1 to m+n-4 do //从上一个状态推下一个
begin
for x1:=1 to m do
begin
y1:=i+3-x1;
if (y1<1) or (y1>n) then continue;
for x2:=x1+1 to m do //大于x1就行,否则有重复
begin
y2:=i+3-x2;
if (y2<1) or (y2>n) then continue;
temp:=0;
if x1>1 then temp:=f[i,x1-1,x2-1];
if y2>1 then temp:=max(temp,f[i,x1,x2]);
if (x1>1) and (y2>1) then temp:=max(temp,f[i,x1-1,x2]);
if x1+1<>x2 then temp:=max(temp,f[i,x1,x2-1]);
f[i+1,x1,x2]:=temp+map[x1,y1]+map[x2,y2];
end;
end;
end;
writeln(f[m+n-3,m-1,m]);
end.
comments powered by Disqus