2058 Problem E 最大子矩阵

问题 E: 最大子矩阵

时间限制: 1 Sec  内存限制: 32 MB
提交: 50  解决: 20
 

题目描述

已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵

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

的最大子矩阵是

9 2
-4 1
-1 8

这个子矩阵的大小是15。

输入

输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。
再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。
已知矩阵中整数的范围都在[-127, 127]。

输出

测试数据可能有多组,对于每组测试数据,输出最大子矩阵的大小。

样例输入

1
27 
3
-40 29 -16 
38 18 22 
24 -35 5 

样例输出

27
78

经验总结

这一题,看似是一个二维求最大连续子序列和问题,实际可以降至一维进行求解(真二维我也不会= =、、),对于确定的从第 A 行到 第 B 行,将 同一列的数相加,最终得到一个一维的数序列,对于这个数序列求最大连续子序列和就可以啦。状态转移方程为: dp [ i ] = max ( a [ i ] , dp [ i - 1 ] + a[ i ] )

正确代码

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=110;
int dp[maxn],M[maxn][maxn],r[maxn],n;
int subSeq()
{
	int ans=r[0];
	dp[0]=r[0];
	for(int i=1;i<n;++i)
	{
		dp[i]=max(r[i],dp[i-1]+r[i]);
		ans=max(ans,dp[i]);
	}
	return ans;
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=0;i<n;++i)
			for(int j=0;j<n;++j)
				scanf("%d",&M[i][j]);
		int res=M[0][0];
		for(int i=0;i<n;++i)
		{
			fill(r,r+maxn,0);
			for(int j=i;j<n;++j)
			{
				for(int k=0;k<n;++k)
				{
					r[k]+=M[j][k];
				}
				res=max(res,subSeq());
			}
		}
		printf("%d\n",res);
	}
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值