首页 > 代码库 > BZOJ1084: [SCOI2005]最大子矩阵
BZOJ1084: [SCOI2005]最大子矩阵
1084: [SCOI2005]最大子矩阵
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1129 Solved: 578
[Submit][Status]
Description
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
Input
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
Output
只有一行为k个子矩阵分值之和最大为多少。
Sample Input
3 2 2
1 -3
2 3
-2 3
1 -3
2 3
-2 3
Sample Output
9
HINT
Source
题解:
DP的难点:
1.状态的表示 用几维变量分别代表什么信息能完整的代表一个状态,这是最重要的
2.状态的转移 枚举这个状态可能转移到什么状态或者可能有什么状态转移来,这是比较容易的
如果状态的转移感到复杂,有可能是状态的表示太过简单
想不到好的方法,就把状态分的细一点
对于本题来说
f[i,j,k]表示左边一列取到i 个,右边取到j个,共取了 k 次
当然并不是全取了,或者说是左边决策到了 i,右边决策到了 j,该进行第k次决策
状态的转移就十分明显了
代码:
1 uses math; 2 const maxn=100+10;maxk=15; 3 var g:array[0..maxn,0..maxk] of longint; 4 s:array[1..2,0..maxn] of longint; 5 f:array[0..maxn,0..maxn,0..maxk] of longint; 6 i,j,k,l,t,n,m,x:longint; 7 procedure init; 8 begin 9 readln(n,m,t);10 for i:=1 to n do11 begin12 for j:=1 to m do begin read(x);s[j,i]:=s[j,i-1]+x;end;13 readln;14 end;15 end;16 procedure work1;17 begin18 fillchar(g,sizeof(g),0);19 for k:=1 to t do20 for i:=k to n do21 begin22 g[i,k]:=g[i-1,k];23 for j:=k-1 to i-1 do24 g[i,k]:=max(g[i,k],g[j,k-1]+s[1,i]-s[1,j]);25 end;26 writeln(g[n,t]);27 end;28 procedure work2;29 begin30 fillchar(f,sizeof(f),0);31 for k:=1 to t do32 for i:=0 to n do33 for j:=0 to n do34 begin35 if (i=0) and (j=0) then continue;36 f[i,j,k]:=max(f[i-1,j,k],f[i,j-1,k]);37 for l:=0 to j-1 do38 f[i,j,k]:=max(f[i,j,k],f[i,l,k-1]+s[2,j]-s[2,l]);39 for l:=0 to i-1 do40 f[i,j,k]:=max(f[i,j,k],f[l,j,k-1]+s[1,i]-s[1,l]);41 if i=j then42 for l:=0 to i-1 do43 f[i,j,k]:=max(f[i,j,k],f[l,l,k-1]+s[1,i]-s[1,l]+s[2,j]-s[2,l]);44 end;45 writeln(f[n,n,t]);46 end;47 48 begin49 assign(input,‘input.txt‘);assign(output,‘output.txt‘);50 reset(input);rewrite(output);51 init;52 if m=1 then work1 else work2;53 close(input);close(output);54 end.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。