【洛谷】P1719 最大加权矩形

洛谷P1719 最大加权矩形

一个n行n列的矩阵,找到和最大的子矩阵。

输入格式
第一行:n,接下来是n行n列的矩阵。

输出格式
最大矩形(子矩阵)的和。

输入输出样例
输入 #1

4
0 -2 -7 0
 9 2 -6 2
-4 1 -4  1 
-1 8  0 -2

输出 #1

15

说明/提示
n<=120

最大子矩阵,一个比较容易想的思路是先算出所有前缀和。然后穷举子矩阵的两个边界点,用前缀和计算出子矩阵的元素和。这样的时间复杂度是 O ( n 4 ) O(n^4) O(n4)
但其实有 O ( n 3 ) O(n^3) O(n3)的做法。我们穷举子矩阵的上边界,比如是第i行,接下来穷举下边界j,就从第i行穷举到最后,但注意这个遍历的同时可以把每一列的元素和叠加算出来。然后,注意到在一维上找最大子段和也是 O ( n ) O(n) O(n)的,有了i到j每一列的元素和,最大子矩阵就只需要找出和最大的两列,即对应叠加结果里的最大子段和。复杂度 O ( n ) × O ( n ) × ( O ( n ) + O ( n ) ) = O ( n 3 ) O(n)\times O(n)\times (O(n)+O(n))=O(n^3) O(n)×O(n)×(O(n)+O(n))=O(n3)。代码如下:

  • a是原矩阵,tmp存储临时子矩阵的叠加和
  • dp用来计算叠加和的最大子段和
#include <iostream>
#include <limits.h>
#include <cstdio>
#include <cmath>
#include <stack>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>
#include <queue>
#include <cstring>
#include <fstream>
#include <map>
#include <list>
using namespace std;
int n,res=INT_MIN;
int a[128][128];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) cin>>a[i][j];
    }
    for(int i=1;i<=n;i++){
        int tmp[128];
        memset(tmp,0,sizeof(tmp));
        for(int j=i;j<=n;j++){
            for(int k=1;k<=n;k++) tmp[k]+=a[j][k];
            int dp=0;
            for(int k=1;k<=n;k++){
                if(dp>0) dp=dp+tmp[k];
                else dp=tmp[k];
                res=max(res,dp);
            }
        }
    }
    cout<<res;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值