Bzoj1084: [SCOI2005]最大子矩阵
题目链接
用f[i,j]表示前i个数,取了j个矩阵的最优值
目标状态:f[n,k]
状态转移:f[i,j]=max(f[i-1,j],f[k,j-1]+sum[i,1]-sum[k,1])(0<=k<=i-1)
用w[i,j,k]表示第一列取到第i个数,第二列取到第j个数,取了k个矩阵的最优值
目标状态:f[n,n,k]
状态转移:f[i,j,k]=max(w[i-1,j,k],w[i,j-1,k]//不取
w[ii,j,k-1]+sum[i,1]-sum[ii,1] ,
w[i,jj,k-1]+sum[j,2]-sum[jj,2]//分别在两列取
(当i=j时)w[ii,ii,k-1]+sum[i,1]+sum[i,2]-sum[ii,1]-sum[ii,2]//在两列都取)
i,j,k,n,m,t,ii,jj:integer;
tot,cnt,ans:longint;
sum:array[0..110,0..2]of longint;
f:array[0..110,0..12]of longint;
w:array[0..110,0..110,0..12] of
longint;
if i>j then exit(i);exit(j);
readln(n,m,k);
fillchar(sum,sizeof(sum),0);
for i:=1 to n do begin
for j:=1 to m do
begin
read(t);
sum[i,j]:=sum[i-1,j]+t;
end;
readln;
end;
if m=1 then begin
fillchar(f,sizeof(f),0);
for i:=0 to n+1 do
f[i,0]:=0;
for i:=1 to n do
for
cnt:=1 to k do begin
f[i,cnt]:=f[i-1,cnt];
for j:=0 to i-1 do
f[i,cnt]:=max(f[i,cnt],f[j,cnt-1]+sum[i,1]-sum[j,1]);
end;
writeln(f[n,k]);
end
else begin
fillchar(w,sizeof(w),0);
for i:=1 to n do
for
j:=1 to n do begin
w[i,j,0]:=0;
for cnt:=1 to k do begin
w[i,j,cnt]:=max(w[i-1,j,cnt],w[i,j-1,cnt]);
for ii:=0 to i-1 do
w[i,j,cnt]:=max(w[i,j,cnt],w[ii,j,cnt-1]+sum[i,1]-sum[ii,1]);
for jj:=0 to j-1 do
w[i,j,cnt]:=max(w[i,j,cnt],w[i,jj,cnt-1]+sum[j,2]-sum[jj,2]);
if i=j then
for ii:=0
to i-1 do
w[i,j,cnt]:=max(w[i,j,cnt],w[ii,ii,cnt-1]+sum[i,1]+sum[i,2]-sum[ii,1]-sum[ii,2]);
end
end;
writeln(w[n,n,k])
end
一开始没仔细看题TAT,后来发现“1≤m≤2”。。。
这提示我萌什么?
我把解法分为m=1和m=2两种情况
首先,sum[i,j]为第j列的前缀和,即表示第j列前i行各个数字的和
①当m=1 时:
②当m=2 时:
【Code】:
var
function max(i,j:longint):longint;
begin
end;
begin
end.