最大子矩阵和问题

题目描述
最大子矩阵和问题。给定m行n列的整数矩阵A,求矩阵A的一个子矩阵,使其元素之和最大。

输入格式
第一行输入矩阵行数m和列数n(1≤m≤100,1≤n≤100),再依次输入m×n个整数

输出格式
输出第一行为最大子矩阵各元素之和,第二行为子矩阵在整个矩阵中行序号范围与列序号范围。

输入样例复制
在这里给出一组输入。例如:

5 6
60 3 -65 -92 32 -70
-41 14 -38 54 2 29
69 88 54 -77 -46 -49
97 -32 44 29 60 64
49 -48 -96 59 -52 25
输出样例复制
在这里给出相应的输出。例如:

321
2 4 1 6

思路:
数据范围为100可以n^3次方解决,参考最大子段和的问题思考。
1.首先枚举列起点为i,终点为j(i<=j<=总列数)的矩阵,然后再分别枚举每次选取连续的哪几行,按照最大子段和的思路判断即可,若加入这一行的值后,res>=0,更新,否则res重新置零,如何判断是否大于当前记录的最大值,记录其值和相应位置即可;

2.用sum[i][j];记录第i行中,前j个数的和;

3.需要注意的是枚举行时,当记录的res<0时,若当前列为j,需要修改记录行的起点要为当前列j+1,因为后面连续的矩阵的行不可能包括这一行,可以联想一下最大子段和中对于小于0时不取的情况;
蓝桥杯这题,但这题不要求求起始行列位置
可以试试
链接: 蓝桥杯历届试题-最大子阵

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e3+10;
LL dp[N][N],p[N][N];
LL sum[N][N];// sum[i][j] 第i行中前j个数的值
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        sum[i][0]=0;
        for(int j=1;j<=m;j++){
            cin>>p[i][j];
            sum[i][j]=sum[i][j-1]+p[i][j];
        }
    }
    LL ans=-1e9;
    int is,js,ie,je;//起点的行,列  终点的行,列
    for(int i=1;i<=m;i++){//枚列起点
        for(int j=i;j<=m;j++){//枚列终点
            LL res=0;
            for(int row = 1,start=1; row <= n; row++){ // 遍历行
                LL temp = sum[row][j] - sum[row][i-1]; // 计算当前行子矩阵的和
                res += temp; // 累加当前行的和
                if(res>ans){// 更新当前最大值
                    ans = res;
                    is = start;
                    ie = row;
                    js = i;
                    je = j;
                } 
                if(res < 0){ // 如果当前和为负数,重置为0,并更新起始行
                    res = 0;
                    start = row + 1;
                }
            }
        }
    }
    cout<<ans<<endl;
    printf("%d %d %d %d\n",is,ie,js,je);
	return 0;
}
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值