动态规划之最大子矩阵和问题

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

输入格式:

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

输出格式:

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

输入样例1:

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

输出样例1:

输出第一行321表示子矩阵各元素之和,输出第二行2 4 1 6表示子矩阵的行序号从2到4,列序号从1到6

321
2 4 1 6

Code:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list> 
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+7;
using namespace std;
#define ARR_SIZE 10001

#define Num 500005
int main()
{
	int row1,row2,col1,col2;
	row1 = row2 = col1 = col2 = 0;
	int arr[101][101];
	int n,m;
    int aaa,sumMax=-INF;
	cin>>n>>m;
    memset(arr,0,sizeof(arr));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin>>aaa;
			arr[i][j]=arr[i][j-1]+aaa;   //用第i行第j列元素表示第i行前j列元素之和,方便后面运算 
		}
	for(int i=1;i<=m;i++)        //此循环用于求出第k行 第i列到第j列 的子矩阵元素之和 
		for(int j=i;j<=m;j++)
		{
			int sum=0;
			for(int k=1;k<=n;k++)
			{
				if(sum<0) {		 //sum等于0时,会发生拖累, 让sum等于0 
					sum=0;
				}
				
				sum+=arr[k][j]-arr[k][i-1];
				
				if(sumMax<sum){
					sumMax=sum;
					row2 = k;
					col1 = i;
					col2 = j;
				}
			}	
		}
	for(int i = 1; i <= row2; i++){  //想了很多办法都没有能够求出行起点row1 后来在同学点拨下暴力回溯,搞定 
		int sum = 0;
		for(int j = i; j <= row2; j++){
			sum += arr[j][col2] - arr[j][col1-1];
		}
		if( sum == sumMax){
			row1 = i;
			break;
		}
		
	}
	
			
		
	cout<<sumMax;
	cout<<endl<<row1<<" "<<row2<<" "<<col1<<" "<<col2;
	return 0;
}

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值