题目链接:https://cn.vjudge.net/contest/311091#problem/B
解析:求二维数组中,一个子矩阵,保证它的和是最大的。
例如:
0 −2 −7 0
9 2 −6 2
−4 1 −4 1
−1 8 0 −2
子矩阵:
9 2
−4 1
−1 8(它的和是最大的)
分析:
1.二维数组有i行,把i行合并成一行,两层for循环,遍历所有的组合情况。
for(int i=1; i<=n; i++)
for(int j=i; j<=n; j++)
黑点,代表数组。
黑线表示i=1时,各种组合情况。
红线代表i=2时,各种组合情况。
蓝线代表i=3时,各种组合情况。
以此类推…
2.输入的时候用前缀和,把每一列向相加。
3.把各种组合情况,从第一个数到最后一个数遍历,找最大值。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int main()
{
int n,a[200][200],sum,mx;
while(~scanf("%d",&n)&&n){
mx=-inf;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&a[i][j]);
if(n==1){
printf("%d\n",a[1][1]);
continue;
}
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++)
a[i][j]+=a[i-1][j];//前缀和
}
for(int i=1; i<=n; i++)
{
for(int j=i; j<=n; j++)
{
sum=0;
for(int k=1; k<=n; k++)//每一种组合情况相当于一行,然后一行的第一个数到第n个数
{
sum+=(a[j][k]-a[i-1][k]);
if(sum<0)
sum=0;
if(sum>mx)
mx=sum;
}
}
}
printf("%d\n",mx);
}
return 0;
}