最大子矩阵和

最大子矩阵和

输入

第1行:M和N,中间用空格隔开(2 <= M,N <= 500)。
第2 - N + 1行:矩阵中的元素,每行M个数,中间用空格隔开。(-10^9 <= M[i] <= 10^9)

输出

输出和的最大值。如果所有数都是负数,就输出0。

输入示例

3 3
-1 3 -1
2 -1 3
-3 1 2

输出示例

7

分析:
      把每一列第i行到第j行之间的和求出来,形成一个数组,于是一个第i行到第j行之间的最大子矩阵和对应于这个和数组的最大子段和。(这样就化为一维的了)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[510][510];
int dp[510];
int main()
{    
    int n ,m ;
    scanf("%d %d",&m,&n);//注意输入顺序,坑。。。 
	int flag = 0; 
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
           {
           	        scanf("%d",&a[i][j]);
           	        if(a[i][j] > 0)  //判断是否全部为负值 
           	          flag = 1;
		   }
		   int sum, ans = 0;
		   for(int i = 1; i <= n; i++)   // 每一行、每一列顺序相加 
		      for(int j = i; j <= n ; j++)
		      {
			          sum = 0;   //转换为一维求最大子段和,每一次都要初始化 
		          for(int k = 1 ; k <= m; k++)   
		         {
		         	   if(i == j)
		         	      {
						   dp[k]  =   a[i][k];  
						 }
		         	    else
		         	    {
		          	  dp[k] = dp[k] + a[j][k];
		                 }
		                 sum += dp[k];
						 ans = max(ans , sum);    
		                   if(sum < 0 )                         
		                    sum = 0; 
				 }
			}
				 if(flag)
				 printf("%d\n",ans);
				 else
				 printf("0\n");
	return 0;
 } 






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值