题目大意
给定一个 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;
}