http://acm.pku.edu.cn/JudgeOnline/problem?id=1050
第一眼看这个题觉得是动态规划,心里一下子就有点胆怯了,因为不熟悉动态规划的使用,但看了Disscuss后就受到启发,有了想法,尽管估计到可能会超时,但还是试了一下,想验证自己的结果是否正确,找了测试实例全过,交上后果然超时,晕!没法了!
超时算法:很容易理解,就是枚举
#include<stdio.h>
#define N 102
int a[N][N],b[N][N];
int main()
{
int n,i,j,k,m,z1,z2,max;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
max=a[i][j];
for(k=i;k<n;k++)
for(m=j;m<n;m++)
{
b[i][j]=0;
for(z1=i;z1<=k;z1++)
for(z2=j;z2<=m;z2++)
b[i][j]+=a[z1][z2];
if(b[i][j]>max)
max=b[i][j];
}
b[i][j]=max;
}
max=b[0][0];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(b[i][j]>max)
max=b[i][j];
printf("%d\n",max);
}
return 0;
}
再次看了牛人代码后,明白了其思路,知道了如何简化程序,以下为AC代码:
#include<stdio.h>
#define N 102
int a[N][N],b[N];
int main()
{
int n,i,j,k,x1,x2,max,sum;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
max=a[0][0];
for(x1=0;x1<n;x1++)
for(x2=x1;x2<n;x2++) //遍历:在第X1行和X2行之间的所有矩阵
{
sum=0;
for(j=0;j<n;j++) //对矩阵每一列求和存入数组b[]
{
b[j]=0;
for(i=x1;i<=x2;i++)
b[j]+=a[i][j];
}
for(k=0;k<n;k++) //找出最大值矩阵
{
if(sum>=0) sum+=b[k];
else sum=b[k];
if(sum>max) max=sum;
}
}
printf("%d\n",max);
}
return 0;
}
按这种思路可以减少for循环次数,节省时间,因此AC了!不过看懂这个思路,真的花了我不少时间,终于明白了,真的好考验人的理解能力啊!但应该还不是最简单的算法,以后有幸得到了再作修改吧!
解法3:DP思想:
#include<stdio.h>
#define N 102
int a[N][N];
int main()
{
int n,i,j,k,m,sum,max;
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
max=-128;
for(i=0;i<n;i++)
for(j=i;j<n;j++)
{
sum=0;
for(k=0;k<n;k++)
{
for(m=i;m<=j;m++)
sum+=a[m][k];
if(sum>max)
max=sum;
if(sum<0)
sum=0;
}
}
printf("%d\n",max);
return 0;
}