您的位置:首页 > 其它

bzoj 1084: [SCOI2005]最大子矩阵 dp

2016-03-03 21:01 232 查看

Description

这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。

Input

第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。

Output

只有一行为k个子矩阵分值之和最大为多少。

我们看到由于m最大只有2,所以就可以用二维来搞定。用f[i,j,k]表示第一列前i个第二列前j个选k个矩形的最大值。然后枚举前面的就好了。记得i=j的时候要分类讨论。
再不懂的看代码。
代码:
var
n,m,p,x,ans,i,j:longint;
s:array[1..2,0..200] of longint;

function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;

procedure work2;
var
i,j,k,l:longint;
f:array[0..200,0..200,0..10] of longint;
begin
fillchar(f,sizeof(f),0);
for k:=1 to p do
for i:=1 to n do
for j:=1 to n do
begin
f[i,j,k]:=max(f[i-1,j,k],f[i,j-1,k]);
for l:=1 to i do
f[i,j,k]:=max(s[1,i]-s[1,l-1]+f[l-1,j,k-1],f[i,j,k]);
for l:=1 to j do
f[i,j,k]:=max(s[2,j]-s[2,l-1]+f[i,l-1,k-1],f[i,j,k]);
if i=j then
for l:=1 to i do
f[i,j,k]:=max(s[1,i]-s[1,l-1]+s[2,i]-s[2,l-1]+f[l-1,l-1,k-1],f[i,j,k]);
if f[i,j,k]>ans then ans:=f[i,j,k];
end;
end;

procedure work1;
var
i,j,k:longint;
g:array[0..100,0..10] of longint;
begin
fillchar(g,sizeof(g),0);
for k:=1 to p do
for i:=1 to n do
begin
g[i,k]:=g[i-1,k];
for j:=1 to i do
g[i,k]:=max(g[i,k],s[1,i]-s[1,j-1]+g[j-1,k-1]);
if g[i,k]>ans then ans:=g[i,k];
end;
end;

begin
readln(n,m,p);
for i:=1 to n do
for j:=1 to m do
begin
read(x);
s[j,i]:=s[j,i-1]+x;
end;
if m=1
then work1
else work2;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: