算法学习之路|最大子阵

题目大意
给定一个 n×m 的矩阵 A,求 A中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中,A的子矩阵指在 A 中行和列均连续的一部分。

输入格式
输入的第一行包含两个整数 n,m(1≤n,m≤50),分别表示矩阵 A 的行数和列数。接下来 n行,每行 m 个整数,表示矩阵 Ai,j​(−1000≤Ai,j​≤1000)。

输出格式
输出一行,包含一个整数,表示 A中最大的子矩阵中的元素和。

样例输入
3 3
2 -4 1
-1 2 1
4 -2 2
样例输出
6
找出状态方程:(状态dpi代表左顶点固定为1,1;右顶点为i,j的矩阵的元素和。)

1.左顶点固定为1,1;右顶点为i,j的矩阵的元素和:

dpi+=dpi-1+dpi-dpi-1;

2.左顶点为i,j;右顶点为i-k,j-l的矩阵(即其中一种子阵)元素和:

dpi-dpi-k-dpi+dpi-k;

#include<iostream>
#include<algorithm>
using namespace std;
int dp[51][51]={0};
//有必要,令dp[0][0~50]==0,dp[0~50][0]==0,当计算仅有一个元素的子矩阵(1,1)时,dp[1][1]-0-0+0。
int main(){
    int n,m;//n是行,m是列
    cin>>n>>m;
    
    for(int i=1;i<=n;i++)//将矩阵存入dp[i][j]中
        for(int j=1;j<=m;j++)
            cin>>dp[i][j];

    for(int i=1;i<=n;i++)//计算整个dp[i][j]
        for(int j=1;j<=m;j++)
            dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];

    int MAX=dp[1][1];//随机取一个值存入max中,当做max的初始值
    
    //所有种子矩阵
    //这里k=1,l=1,表示取的子矩阵为一个元素
    //k=2,l=2,表示子矩阵为两行两列的四个元素
    for(int k=1;k<=n;k++)//行
        for(int l=1;l<=m;l++)//列
            //一种子矩阵的所有种取法
            for(int i=k;i<=n;i++)
                for(int j=l;j<=m;j++)
                    MAX=max(MAX,dp[i][j]-dp[i-k][j]-dp[i][j-l]+dp[i-k][j-l]);
    cout<<MAX;
}
上一篇:Java程序运行机制


下一篇:IDC:银行业和制造业推动全球大数据和业务分析市场双位数增长