二维的最大子段和,dp
先预处理,sum[i][j]表示矩阵1~i行,第j列的和,用递推可在O(n^2)时间解决
再枚举两行i1,i2(1<=i1<=i2<=n),将夹在i1和i2中间的同一列的元素进行"压缩"
其和可用sum[i2][j]-sum[i1-1][j]表示,然后就是做一维的最大子段和了
一个累加器,从左往右O(n)扫一遍,加上当前元素>0就更新best,<0就把累加器清零
- //3446710_AC_32MS_348K
- #include<iostream>
- using namespace std;
- #define MAXN 101
- int w[MAXN][MAXN];
- int sum[MAXN][MAXN];
- int i,j,k,best,n,f;
- int main()
- {
- //freopen("d:/in.txt","r",stdin);
- for (j=0;j<MAXN;++j)
- {
- sum[0][j]=0;
- }
- while (cin>>n)
- {
- for (i=1;i<=n;++i)
- {
- for (j=1;j<=n;++j)
- {
- cin>>w[i][j];
- }
- }
- for (j=1;j<=n;++j)
- {
- sum[1][j]=w[1][j];
- for (i=2;i<=n;++i)
- {
- sum[i][j]=sum[i-1][j]+w[i][j];
- }
- }
- best=0;
- for (i=1;i<=n;++i)
- {
- for (k=i;k<=n;++k)
- {
- f=0;
- for (j=1;j<=n;++j)
- {
- if (f+sum[k][j]-sum[i-1][j]<0)
- {
- f=0;
- }
- else
- {
- f+=sum[k][j]-sum[i-1][j];
- if (f>best)
- {
- best=f;
- }
- }
- }
- }
- }
- cout<<best<<endl;
- }
- return 0;
- }