1. 程式人生 > >51 nod1051最大和子矩陣

51 nod1051最大和子矩陣

題目:

https://cn.vjudge.net/contest/180638#problem/A

一個M*N的矩陣,找到此矩陣的一個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。

例如:3*3的矩陣: -1 3 -1 2 -1 3 -3 1 2 和最大的子矩陣是: 3 -1 -1 3 1 2

思路:這題的基礎題是最大子段和,不同的是那個是以為陣列,這個是二維陣列;所以進行轉換。二維陣列不確定的是第幾行到第幾行是最小子矩陣的行,所以可以進行遍歷,假設行確定之後,列的確定就和普通的最小子矩陣和沒啥區別了。用result[k]儲存i到j行的第k列和,由於j從i開始往下,所以result[k]+=a[j][k]即可,利用上一次的結果。

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 505
int a[maxn][maxn];
ll result[maxn];
int main()
{
	int m, n;//m列n行
	ll temp = 0,maxij=0;
	while (cin >> m >> n)
	{
		maxij = 0;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				cin >> a[i][j];

		for (int i = 0; i < n; i++)//確定最大在行ij之前
		{
			for (int j = i; j < n; j++)//求出ij之前的每一列的值,然後用最大子段和
			{
				 temp = 0;
				for (int k = 0; k < m; k++)
				{
					if (i == j)
						result[k] = a[j][k];
					else
					  result[k] += a[j][k];//因為j>=i,result可以利用上一個迴圈的k

					if (temp > 0)
						temp += result[k];//最小子段和的部分
					else
					temp = result[k];
					maxij = max(maxij, temp);
				}
			}
		}
		cout << maxij << endl;
	}
	return 0;
}