这道题和P1115 最大子段和思路类似。
只是将一维升到二维。
很重要的解决思路,矩阵压缩。
如果能把二维降到一维,那就好处理了。
假设有一个矩阵:
-5 6 4
1 -2 6
2 1 -3
想得到其中任意一个矩阵,我们不妨先确定列。
很明显用两个循环嵌套可以解决。
假设我们取2,3列
6 4
-1 6
1 -3
列取好之后那么每一行的和值就是确定的了。
注意:用前缀和可以优化时间。
10
5
-2
接下来我们再在这个一维数组中求最大子序列的和。
就和P1115的做法一样了!
完整代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <math.h>
#include <functional>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <cstdio>
#include <list>
#include <queue>
#include <set>
#include <unordered_map>
#define ll long long
using namespace std;
int n;
int k[200][200];
int num[200];
int max1=-1000000000;
int main(){
cin>>n;
int i,j,x,s;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
cin>>x;
k[i][j]=k[i][j-1]+x;
}
}
for(i=1;i<=n;i++){
for(j=i;j<=n;j++){
for(x=1;x<=n;x++){
num[x]=k[x][j]-k[x][i-1];
}
s=0;
for(x=1;x<=n;x++){
s+=num[x];
if(s<0) s=0;
max1=max(max1,s);
}
}
}
cout<<max1;
}