矩阵前缀和应用1:最大和子矩阵 前缀和+动态规划

关于矩阵前缀和【矩阵前缀和:常数时间求一子矩阵的加和

给一个m*n的矩阵,找到一个子矩阵使其里面的数字加和最大,输出这个最大值

首先想到暴力算法:
枚举矩阵行列,复杂度O(n4),然后对每个枚举的子矩阵,计算矩阵内的加和O(n2),总复杂度O(n6)

通过前缀和,可以把计算加和的时间变为O(1),总复杂度O(n4),还是有点大

优化:引入动态规划中的最大子区间问题

类似的题目

已知一个一维数组,如何求一区间使得区间内加和最大?暴力枚举左右端点的复杂度O(n2),但是动态规划可以O(n)完成

定义状态
dp[i]表示以下标 i 的元素结尾的某个子区间的最大加和

状态转移
对于以下标 i 元素结尾的子区间,必须选取下标i的元素,但是可以主动选择是否丢弃前面的区间

  1. 下标i元素 a[i]加在【以 i-1 下标结尾的最大和子区间】后面
  2. 下标 i 元素单独形成一个子区间

比较两个结果,选取大的作为当前 i 下标结尾的区间的答案

最后遍历区间右端点,找最大即可

回到矩阵的问题:

现在我们已知用O(n)时间求一个一维数组最大子区间的问题,那么对于矩阵,我们可以花费O(n2)的时间,枚举起始行和结束行

在起始行和结束行已经确定的情况下,只要确定起始列,和结束列,就能够确定一个矩阵,那么我们套用上面的动态规划,对所有的列,确定一个区间使得在这个区间内,被起始行和结束行夹逼的列区间,加和值最大(加和值通过前缀和可以O(1)查询)

确定起始列,结束列,相当于一维数组的区间左端点,右端点

这里枚举起始行,结束行,起到降维的效果

在这里插入图片描述

O(n2)枚举起始行,结束行,再用O(n)时间找到最大的区间,总复杂度O(n3)

代码

在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int a[1509][1509], dp[1509]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值