题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=104
分析:这道题目是44题http://acm.nyist.net/JudgeOnline/problem.php?pid=44的二维扩展.
先说第44题:采用的策略是记录到当前位置连续字串的最大和,如果第i个数之前的最大和为正数,则加上第i个数,否则最大字串和就要从当前开始计算。可得到转移方程为:tmp=(tmp>=0?tmp:0)+a; sum=tmp>sum?tmp:sum;(tmp为当前最大字串和,sum为所求最大和,a为当前位置的数)。
下面是44题代码:
#include <stdio.h>
int main()
{
int K,n,i,tmp,sum,a;
scanf("%d",&K);
while(K--)
{
scanf("%d",&n);
tmp=sum=0x80000001;
for(i=0;i<n;i++)
{
scanf("%d",&a);
if(tmp<0)
tmp=a;
else
tmp+=a;
if(tmp>sum)
sum=tmp;
}
printf("%d\n",sum);
}
return 0;
}
对于二维数组,计算最大子矩阵和多了从任一行到下面任一行的情况,如果使用暴力,难免超时,记得对于数组我们经常采用的一个技巧:记录当前的子数组的和,这里同样采用这种策略,把列压缩。
下面是代码:
#include <iostream>
using namespace std;
int main()
{
int T,r,c,i,j,k,ans,max,tmp;
int a[102][102]={0} ;
cin>>T;
while(T--)
{
cin>>r>>c;
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
{
cin>>a[i][j];
a[i][j]=a[i][j]+a[i-1][j];
}
ans=0x80000001;
for(k=0;k<r;k++)
{
for(i=k+1;i<=r;i++)
{
max=0;
for(j=1;j<=c;j++)
{
tmp=a[i][j]-a[k][j];
if(max<0) max=0;
max+=tmp;
if(max>ans) ans=max;
}
}
}
cout<<ans<<endl;
}
return 0;
}