题目描述 Description
HR神犇在成功攻略ZX后,花心的他举办了一届选(yu)美(yue)大赛。
由于HR神犇有重度不规则形体恐惧症,所以他要求选美的女孩纸要站成一个正方形。因为HR神犇的眼光是非常之高的,所以他要求选出来的女孩美貌值总和最大,由于HR神犇的精力非常多,所以选出来的女孩数量没有限制。当然,一些女孩纸比较丑,美貌值可能为负数。而且,HR神犇的重度不规则形体恐惧症使他要求选出来的女孩纸形成一个矩形(不是正方形)(实心的)。
HR神犇决定,只要你成功帮他找出这个矩形,他就给你10000000000 mod 10元。
输入描述 Input Description
第一行一个整数n,表示正方形的边长。
接下来n行,每行n个整数,表示每个女孩的美貌值。
输出描述 Output Description
输出只有一个整数,表示最大的美貌值总和。
样例输入 Sample Input
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
样例输出 Sample Output
15
数据范围及提示 Data Size & Hint
对于30%的数据,1<=n<=10,美貌值<=100
对于50%的数据,1<=n<=50,美貌值<=104
对于100%的数据,1<=n<=200,美貌值不会超过int64的存储范围
思路就是最大子矩阵和
这篇博客讲的很好大家可以看看最大子矩阵和
简述一下
就是先处理处从1到第n行(n=2,3,4…)的前n行的和
求第i行到第j的和时用到了数列的性质
比如 a1=-2,a2=2,a3=1,a4=8,
Sn代表前n项的和
s1=a1=-2,
s2=a1+a2=0,
s3=a1+a2+a3=1,
s4=a1+a2+a3+a4=9;
所以 第2项到第4项的和为
s4-s1=a1+a2+a3+a4-a1=a2+a3+a4=2+1+8=9-(-2)=11;
所以第i行到第j行的和为 Sj-S(i-1),(i,j均为下标)
然后在做最大子段和,代表了第i行到第j行中,第k列到第l列的和
也就是以 (i,j)和(k,l)为顶点的子矩阵
#include<cstdio>
#include<iostream>
#define ll long long
#define MAXN 210
using namespace std;
ll a[MAXN][MAXN];
ll tot,ans;
int n;
inline void read(ll&x) {
int f=1;x=0;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=10*x+c-48,c=getchar();
x=x*f;
}
int main() {
freopen("1.in","r",stdin);
ll x;
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) {
read(x);
a[i][j]=x;
a[i][j]+=a[i-1][j];
}
ans=-1;
for(int i=0;i<n;i++) {
for(int j=i+1;j<=n;j++) {
tot=0;
for(int k=1;k<=n;k++) {
if(tot<0) tot=a[j][k]-a[i][k];
else tot+=a[j][k]-a[i][k];
if(tot>ans) ans=tot;
}
}
}
printf("%lld\n",ans);
return 0;
}