最大子阵-蓝桥

题目描述
给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。

其中,A的子矩阵指在A中行和列均连续的一块。

样例说明
取最后一列,和为10。
数据规模和约定
对于100%的数据,1< =n, m< =500,A中每个元素的绝对值不超过5000。

输入
输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。
输出
输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
样例输入
3 3
-1 -4 3
3 4 -1
-5 -2 8
样例输出
10

思路
在选定子矩阵中我们要先选定行范围载选定列范围
for example:对于如下矩阵
-1 -4 3
3 4 -1
-5 -2 8
1先看0-0行矩阵,设为subMx,再在该子矩阵subMx中选取对应连续的列来确定在0-0行子矩阵(设为subsubMx)中最大的子矩阵,此时最大的subsubMx=3;
2又来到0-1行矩阵subMx,不像1中只有一列很好比较,我们需要一个一维数组sub[]用于存储subMx中对应列的和。在
1中数组sub的值应该是-1,-4,3;在此例中sub的值应该是-1+3,-4+4,3-1即-2,0,2,此时最大的subsubMx=2;
3重复类似2的操作走到0-2行
*4走到1-1行
*5走到1-2行
*6走到2-2行
结束

#include<iostream>
#include<cstdio>
#define inf 0x7fffffff
using namespace std;
int n,m;
int mp[505][505];
int getmax(int sub[])
{
	int maxx,tmp,begin;
	maxx=-inf;
	begin=sub[0];
	for(int i=1;i<m;i++)
	{
		if(begin+sub[i]>sub[i])
			begin=begin+sub[i];
		else
			begin=sub[i];
		if(begin>maxx)
			maxx=begin;
	}
	return maxx;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			scanf("%d",&mp[i][j]);
	int tmp;
	int ans=-inf;
	for(int i=0;i<n;i++)//枚举行级子矩阵第i行到第j行 
	{
		int sub[505]={0};//sub用于求第i行到第j行的对应第k列元素之和 
		for(int j=i;j<n;j++)
		{
			int k;
			for(k=0;k<m;k++)
				sub[k]+=mp[j][k];
			tmp=getmax(sub);//得到行级子矩阵的列级子矩阵的最大值 也就是求第i行到第j行这个子矩阵里0-m列中最大的子矩阵 
			if(tmp>ans)
				ans=tmp;
		}
	}
	cout << ans;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值