最大子矩阵

来源:互联网 发布:数据挖掘 模型评估 编辑:程序博客网 时间:2024/05/17 02:54
总时间限制: 
1000ms 
内存限制: 
65536kB
描述
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是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]。
输出
输出最大子矩阵的大小。
样例输入
40 -2 -7 0 9 2 -6 2-4 1 -4  1 -18  0 -2
样例输出
15
来源

翻译自 Greater New York 2001 的试题



这是一维最大子序和的扩展题,考虑二维的情况,如果是暴力枚举会达到n^4的复杂度

我们可以将其压缩成一维的,然后用最大子序和的方法求解


#include <bits/stdc++.h>using namespace std;int a[105][105];int N;int d[105];int getMax(int t[]){    //int ans = 0;    int maxans = -0x7fffffff;    for(int i = 1; i <= N; i++)    {        if(d[i-1]+t[i]>t[i])            d[i] = d[i-1]+t[i];        else d[i] = t[i];        maxans = max(maxans, d[i]);    }    return maxans;}int main(){    cin >> N;    for(int i = 1; i <= N; i++)    {        for(int j = 1; j <= N; j++)        {            cin >> a[i][j];            a[i][j] += a[i][j-1];        }    }    int ans = 0;    int tmp[105];    for(int i = 1; i <= N; i++)    {        for(int j = i; j <= N; j++)        {            for(int k = 1; k <= N; k++)            {                tmp[k] = a[k][j]-a[k][i-1];            }            ans = max(ans, getMax(tmp));        }    }    cout << ans << endl;    return 0;}