题目链接点击打开链接
思路
拿样例来说
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
一边读入的时候一边求前缀和
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&x),a[i][j]=a[i][j-1]+x;
我们只需要前缀和所以读入的就没有了,另外开一个数组也可以
然后这个4*4的a[i][j]矩阵变成了
0 -2 -9 -9
9 11 5 7
-4 -3 -7 -6
-1 7 7 5
这样有了前缀和之和我们不必要for一遍求和了,而只要a[w][i]-a[w][j]就可以得到第w行从j+1到i的和
这样子我们首先两个for循环模拟子矩阵的行i=1 to n,j=0 to i-1
这样只是一行所以我们得再for一遍w模拟竖排
把它压缩成了一竖排
a[1][i],a[2][i]...a[w][i]——求最大子串和!
代码附上
#include<algorithm>
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int ans=-21000000,a[101][101]={0},tot,x,n,y[101];
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&x),a[i][j]=a[i][j-1]+x;//前缀和
for (int i=1;i<=n;i++)
for (int j=0;j<i;j++)//模拟行的长度
{
//memset(y,0,sizeof(y));//这里可以不memset,反正每次处理都是处理前一个处理过的
for (int w=1;w<=n;w++)
{
if (a[w][i]+y[w-1]<0) y[w]=0;
else
y[w]=y[w-1]+a[w][i]-a[w][j];//a[w][i]-a[w][j]等于a[w][j+1]到a[w][i]的和
ans=max(ans,y[w]);
}//上面四行求最大子串和,最大子串和也就是小于0的就复制为零,最后取max
}
printf("%d",ans);
}