最大子矩阵之和
题目
给出一个N [2<=N<=100],并给出一个N*N的矩阵,矩阵中的数为[-127,127]之间。求出矩阵中一块子矩阵的最大和。
比如:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
和最大的子矩阵应该是这个:
9 2
-4 1
-1 8
它的和是15。
Sample Input
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
Sample Output
15
思路
这题跟糖果盒几乎一样,只是不用考虑0的问题。
还是一样先求出每一列的前缀和,再dp
l表示当前情况的最大子矩阵之和,f[j][k]表示第j行第k个的前缀和值,
f[i-1][k]表示第i-1行第k个的前缀和值。
状态转移方程:
l
+
=
f
[
j
]
[
k
]
−
f
[
i
−
1
]
[
k
]
l+=f[j][k]-f[i-1][k]
l+=f[j][k]−f[i−1][k]
1
<
=
i
=
j
<
=
n
,
1
<
=
k
<
=
n
1<=i=j<=n,1<=k<=n
1<=i=j<=n,1<=k<=n
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std;
long long n,f[1001][1001],ans,d;
void in(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>f[i][j];
f[i][j]+=f[i-1][j];//前缀和
}
}
}void DP(){
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
long long l=0;
for(int k=1;k<=n;k++){
l+=f[j][k]-f[i-1][k];//状态转移
ans=max(l,ans);//最大的答案
}
}
}
}
int main(){
in();
DP();
printf("%d",ans);
}