动态规划:
对于每一行,f(i,j)表示从i到j这一子段单独操作可以达到的最大权值。
有状态转移方程:f(i,j) = 2*max(a(i)+f(i+1,j),a(j)+f(i,j-1))
边界f(i,i)=2*a(i)
程序:
program game;
type
arr=array[0..50] of integer;
var
f:array[0..80,0..80,0..50] of integer;
s:array[1..80,0..50] of integer;
i,j,k,n,m:integer;
ans:arr;
function max(a,b:arr):arr;
var
k:integer;
begin
if a[0]>b[0] then exit(a)
else if b[0]>a[0] then exit(b)
else
begin
k:=a[0];
while (a[k]=b[k]) and (k>0) do dec(k);
if a[k]>b[k] then exit(a)
else exit(b);
end;
end;
function times(a:arr;b:integer):arr;
var
c:arr;
i,j:integer;
begin
fillchar(c,sizeof(c),0);
for i:=1 to a[0] do
c[i]:=a[i]*b;
for i:=1 to a[0] do
if c[i]>=10 then
begin
inc(c[i+1],c[i] div 10);
c[i]:=c[i] mod 10;
end;
i:=a[0];
while c[i+1]>0 do
begin
inc(i);
if c[i]>=10 then
begin
inc(c[i+1],c[i] mod 10);
c[i]:=c[i] mod 10;
end;
end;
c[0]:=i;
times:=c;
end;
function push(a,b:arr):arr;
var
c:arr;
i,len:integer;
begin
fillchar(c,sizeof(c),0);
if a[0]>b[0] then len:=a[0]
else len:=b[0];
for i:=1 to len do
begin
c[i]:=a[i]+b[i]+c[i];
if c[i]>=10 then
begin
inc(c[i+1]);
c[i]:=c[i] mod 10;
end;
end;
if c[i+1]>0 then inc(len);
c[0]:=len;
push:=c;
end;
begin
assign(input,'game.in');
reset(input);
assign(output,'game.out');
rewrite(output);
fillchar(ans,sizeof(ans),0);
readln(n,m);
for i:=1 to n do
begin
fillchar(s,sizeof(s),0);
fillchar(f,sizeof(f),0);
for j:=1 to m do
begin
read(k);
if k=0 then s[j,0]:=1;
while k>0 do
begin
inc(s[j,0]);
s[j,s[j,0]]:=k mod 10;
k:=k div 10;
end;
end;
readln;
for j:=1 to m do
f[j,j]:=times(s[j],2);
for j:=m-1 downto 1 do
for k:=j+1 to m do
f[j,k]:=times(max(push(f[j,k-1],s[k]),push(f[j+1,k],s[j])),2);
ans:=push(ans,f[1,m]);
end;
for i:=ans[0] downto 1 do
write(ans[i]);
writeln;
close(input);
close(output);
end.