动归进阶 ~最大子矩阵~

【试题描述】

已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是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]。
【输出要求】

输出最大子矩阵的大小。
【输入样例】

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

【输出样例】

15

题解:

include <bits/stdc++.h>

using namespace std;

int a[105][105],f[105][105];//前i个数在体积不超过j时最优解

int main()
{
int n;
cin >> n;
for (int i = 1; i <= n;i++)
for (int j = 1; j <= n;j++)
cin >> a[i][j];

for (int i = 1; i <= n;i++)
	f[1][i] = f[1][i - 1] + a[1][i];
for (int i = 1; i <= n;i++)
	f[i][1] = f[i - 1][1] + a[i][1];
for (int i = 2; i <= n;i++)
{
	for (int j = 2; j <= n;j++)
	{
		f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + a[i][j];
	}
}
int ans = 0;
for (int i = 1; i <= n;i++)
{
	for (int j = 1; j <= n;j++)
	{
		for (int u = 1; u <= i;u++)
		{
			for (int v = 1; v <= j;v++)
			{
				int t = f[i][j] -  f[u - 1][j] - f[i][v - 1] + f[u - 1][v - 1];
				ans = max(ans , t);
			}
		}
	}
}
cout << ans << "\n";//2
return 0;

}

posted @ 2024-12-26 19:17  luorundong  阅读(34)  评论(0)    收藏  举报