最大子矩阵

【题目描述】

已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1×11×1)子矩阵。

比如,如下4×44×4的矩阵

09412218764002120−2−7092−62−41−41−180−2

的最大子矩阵是

94121892−41−18

这个子矩阵的大小是1515。

【输入】

输入是一个N×NN×N的矩阵。输入的第一行给出N(0<N100)N(0<N≤100)。再后面的若干行中,依次(首先从左到右给出第一行的NN个整数,再从左到右给出第二行的NN个整数……)给出矩阵中的N2N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[127,127][−127,127]。

【输出】

输出最大子矩阵的大小。

【输入样例】

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

【输出样例】

15

先来吐槽一下,这尼玛题目竟然放在贪心的练习题里我也是很懵逼(可能是我太菜了~~)

这题其实是dp里的经典题,不过那个题是一维的,现在变成二维的了

也很简单就是前i-1的最大和,然后只考虑第i个取不取

方程:  f[i]=max(f[i-1],f[i-1]+a[i])

如果把二维数组看成是纵向的一维数组和横向的一维数组,就ok了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
using namespace std;
inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int maxsub(int a[],int n) {
    int i,max=0,b=0;
    for(i=0; i<n; i++) {
        if(b > 0)
            b += a[i];
        else
            b = a[i];
        if(b > max)
            max = b;
    }
    return max;
}
int n,i,j,k,ans,t;
int dp[101][101],a[101];
int main() {

    while(cin>>n) {
        for(i=0; i<n; i++)
            for(j=0; j<n; j++)
                cin>>dp[i][j];
        ans = 0;
        for(i=0; i<n; i++) {
            memset(a,0,sizeof(a));
            for(j=i; j<n; j++) {
                for(k=0; k<n; k++)
                    a[k] += dp[j][k];
                t = maxsub(a,n);
                if(t > ans) ans = t;
            }
        }
        cout<<ans<<endl;
    }
}


原文地址:https://www.cnblogs.com/pyyyyyy/p/10766740.html