动归进阶 ~最大子矩阵~
【试题描述】
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是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;
}

浙公网安备 33010602011771号