最大子阵

问题描述:

Description

给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中,A的子矩阵指在A中行和列均连续的一块。

Input

输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。

(1 <= n, m <= 50,1 <= n,  m <= 500,A中每个元素的绝对值不超过5000)

Output

输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。

Sample Input

3 3-1 -4 33 4 -1-5 -2 8

Sample Output

10
分析:当m,n的数据在100左右,可以直接利用求一维数组的最大连续区间方法直接搞定。但是当数据量达到500就必定超时,那么就必须使用二维数组记录这列的和,例如第i行第j列,必须记录下从0行到当前行对应的j列的和,sum[i][j]=a[0][j]+....+a[i][j]。
当1<=n,m<=100时可用这个方法(适合小数据)

AC代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=600,inf=-1000000000;
int a[maxn][maxn];
int n,m;
long long mergesort()
{
    long long sum=inf;
    long long key;
    for(int i=1;i<=n;i++)
        for(int j=0;j<=n-i;j++)
        {
            long long temp=inf;
            for(int k=m-1;k>=0;k--)
            {
                key=0;
                for(int x=j;x<=j+i-1;x++)
                {
                    key+=a[x][k];
                }
                temp=max(key,temp+key);
                sum=max(temp,sum);
            }
        }
    return sum;
}
int main(void)
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            cin>>a[i][j];
        }
    cout<<mergesort()<<endl;
    return 0;
}



当1<=n,m<=500时,以上代码会超时,至于两组代码的差距(即优化)当你看懂了自然就明白了。

AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=505,inf=-100000000;
int a[maxn][maxn],sum[maxn][maxn];
int n,m;
int cur;
int solve()
{
	cur=inf;
	for(int i=0;i<=n;i++)
		for(int j=i+1;j<=n;j++)
		{
			int temp=inf;
			for(int k=m;k>=1;k--)
			{
				int x=sum[j][k]-sum[i][k];
				temp=max(x,x+temp);
				cur=max(cur,temp);
			}
		}
		return cur;
}
int main(void)
{
	cin>>n>>m;
	memset(sum[0],0,sizeof(sum[0]));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			sum[i][j]=sum[i-1][j]+a[i][j];
		}
	cout<<solve()<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值