最大子矩阵和
来源:互联网 发布:如何开淘宝话费充值店 编辑:程序博客网 时间:2024/04/27 19:26
前言:
今日在打比赛时遇到了一道求最大子矩阵的题目,对于渣渣的我非常困难。在网上查找,发现很少有博客是讲得清晰的。所以决定自作一篇有关于此的博客。
题目:
给定一个矩阵,都是整数,其中(n≤500),求出其中的最大子矩阵
解题思路:
O(n^2*n^2*n^2)的做法:
很容易想到,可以枚举一个矩阵的左上角和右下角的坐标确定这个矩阵,然后,再用两个循环进行统计
O(n^2*n^2)的做法:
对于上面的方法,提前处理一个前缀和,即可省去后面统计的时间复杂度。
正解,即O(n³)事实上并没有这么多:
想要做对这道题,我们先要明白一个最大子段和算法的做法:
例如数字a={8,-2,3,-11,5},我们需要求出一段连续数字的最大和是什么
我们的思想是DP
设f[i]表示从1~i这些位置中的最大子段和
如何转移?对于当前的点i,我们只有两种状态,选择与上一个子段和连接或者自己重新构成一个字段和。
若选,则与1~i-1的最大字段和有关系,即1~i-1的最长字段和加上当前的a[i],重新构成一个子段和
若不选,则与1~i-1最大子段和没有关系,自己重新构成了一个字段和
两者取之小者,亦可解决
列出状态转移方程:f[i]:=max(a[i],f[i-1]+a[i])
时间复杂度 O(n)
---------------------------------分界线-----------------------
有了前面的铺垫,那么这道题就容易多了。
我们可以根据最大子段和,求出最大子矩阵和,无非就是1维改成了2维
我们先选择一连串几行数,把他们每一列累加起来,即最大子段和中的a数组(这里可以用前缀和实现),然后按照如上做法实现即可。
对于选择一连串行数,我们需要两个循环
i表示选择多少行连续的数 O(n)
j表示从第j行开始往下选i行 O(n)没有这么多
最后做一次最长子段和O(n),即O(n³)
代码实现:
uses math;var n,m,i,j,k,maxnum,maxn,ans:longint; a,s:array[0..500,0..500] of longint; f:array[0..500] of longint;begin readln(n,m); for i:=1 to n do for j:=1 to m do begin read(a[i,j]); s[i,j]:=s[i-1,j]+a[i,j];//前缀和 end; for i:=1 to n do for j:=1 to n-i+1 do//如上 begin fillchar(f,sizeof(f),0); maxnum:=0; for k:=1 to m do//最大子段和 begin f[k]:=max(f[k-1]+s[j+i-1,k]-s[j-1,k],s[j+i-1,k]-s[j-1,k]); if f[k]>maxnum then maxnum:=f[k]; end; if maxnum>maxn then maxn:=maxnum; end; writeln(maxn);end.若有不懂的地方可以在下方评论中提出来。
- 最大子矩阵和
- 最大子矩阵和
- 最大子矩阵和
- 最大子矩阵和
- 最大子矩阵和
- 最大子矩阵和
- 最大子矩阵和
- 最大子矩阵和
- 最大子矩阵和
- 最大矩阵子和
- 最大子矩阵和
- 最大子矩阵和
- 最大和子矩阵
- 最大和子矩阵
- 最大子矩阵和
- 最大和子矩阵
- 最大子矩阵和
- 最大子矩阵和
- 23. Merge k Sorted Lists
- Ubuntu16.04下Apache2的操作
- Fast convnets using group-wise brain damage
- 改变Activuty的透明度
- http协议
- 最大子矩阵和
- git 常见问题
- DPM(Deformable Parts Model)--原理
- 只有不停奔跑
- matlab矩阵操作大全
- 【ife】任务四十四:多功能相册之瀑布布局
- mysql 嵌套查询
- undo log与redo log原理分析
- Ubuntu下deb包的安装方法