noip2007矩阵取数游戏 2008.11.5
注意:比大小位数不相同时,取位数大的数大;当位数相同时,要从最高位开始比较,相同,则往下比,不相同,则大的数就大。(我刚开始,弄成了从最低位开始比较,故,wa了20多分钟)
小结:这道题,我打了不下5遍,一定要先想好,在纸上把每个细节都确定了,并确定这是最好的算法,最好的数据结构,在开始敲程序,敲总是很快的,不要担心,但一定在敲之前,保证正确!
program game;
const fin='game.in';fout='game.out';
maxn=80;
p=10000000;p1=7;
type
arr=array[0..50]of longint;
var f:array[1..maxn,1..maxn]of arr;
f1,f2:text;
k,n,m,i,j:longint;
max:arr;
a:array[1..maxn,1..maxn]of longint;
procedure init;
begin
assign(f1,fin);reset(f1);
assign(f2,fout);rewrite(f2);
read(f1,n,m);
for i:=1 to n do
for j:=1 to m do read(f1,a[i,j]);
fillchar(max,sizeof(max),0);
end;
procedure add(a1,b1:arr;var s:arr);
var i,j,l:longint;
begin
fillchar(s,sizeof(s),0);
if a1[0]>b1[0] then l:=a1[0] else l:=b1[0];
for i:=1 to l do
begin
s[i]:=a1[i]+b1[i]+s[i];
s[i+1]:=s[i+1]+s[i] div p;
s[i]:=s[i] mod p;
end;
if s[l+1]<>0 then
begin s[l+1]:=s[l+1]+s[l] div p;
s[l]:=s[l] mod p;
inc(l);
end;
s[0]:=l;
end;
function maxin(x1,x2:arr):arr;
var i:longint;
begin
if x1[0]>x2[0] then exit(x1)
else if x1[0]<x2[0] then exit(x2)
else
begin
i:=x1[0];
while (x1[i]=x2[i]) and(i>1)do dec(i);
if x1[i]>x2[i] then exit(x1) else exit(x2);
end;
end;
procedure dp;
var w,i,j,k:longint;x1,x2:arr;
begin
for w:=1 to n do
begin
fillchar(f,sizeof(f),0);
for i:=1 to m do
begin
f[i,i,0]:=1;
f[i,i,1]:=a[w,i]*2;
end;
for k:=2 to m do
for i:=1 to m-k+1 do
begin
j:=i+k-1;
fillchar(x1,sizeof(x1),0);
fillchar(x2,sizeof(x2),0);
x1[0]:=1;x1[1]:=a[w,j];
add(f[i,j-1],x1,x1);
x2[0]:=1;x2[1]:=a[w,i];
add(f[i+1,j],x2,x2);
f[i,j]:=maxin(x1,x2);
add(f[i,j],f[i,j],f[i,j]);
end;
add(f[1,m],max,max);
end;
end;
procedure print;
var i,l,j:longint;ch:string;
begin
write(f2,max[max[0]]);
for i:=max[0]-1 downto 1 do
begin
str(max[i],ch);
for j:=1 to p1-length(ch) do
write(f2,0);
write(f2,max[i]);
end;
end;
begin init;
dp;
print;
close(f1);
close(f2);
end.