您的位置:首页 > 其它

经典动态规划——HDU1081 To The Max 最大子矩阵问题

2013-07-10 09:01 369 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1081

题目大意:给定1个n*n矩阵,求最大子矩阵(矩阵元素之和最大)。

解题思路:

这个题目和那个最大连续子序列是比较像的,只是维数不同而已。

如果能把二维的问题转化成一维的,那么这个问题就迎刃而解了。

二维转一维的方法就是枚举任意两行,然后求出这两行之间任意一列之和,

这样就得到了一个一维数组,接下来的做法就是求最大连续子序列。

这个题目需要预处理,sum[i][j],表示前i行第j列之和,b[k]=sum[j][k]-sum[i][k];

最大连续子序列的状态转移方程:c[k]=max(c[k-1]+b[k],b[k]);

源代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
int a[101][101];
int sum[101][101];  //表示前i行第j列之和
int b[101];         //表示最后需要进行运算的数据
int c[101];
int main()
{
int n,i,j,mmax,k;
while(scanf("%d",&n)==1)
{
memset(a,0,sizeof(a));
memset(sum,0,sizeof(sum));
memset(b,0,sizeof(b));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
//预处理前i行第j列的和
//第1行之和
for(i=1;i<=n;i++)
{
sum[1][i]=a[1][i];
}
for(i=2;i<=n;i++)
{
for(j=1;j<=n;j++)
{
sum[i][j]=sum[i-1][j]+a[i][j];
}
}
//枚举每两行求取最大子矩阵之和
mmax=-99999999;
for(i=0;i<=n-1;i++)
{
for(j=i+1;j<=n;j++)
{
memset(b,0,sizeof(b));
for(k=1;k<=n;k++)
{
b[k]=sum[j][k]-sum[i][k];
}
//求最大子段和
memset(c,0,sizeof(c));
c[1]=b[1];
if(c[1]>mmax)   mmax=c[1];
for(k=2;k<=n;k++)
{
if(c[k-1]>0)    c[k]=c[k-1]+b[k];
else    c[k]=b[k];
if(c[k]>mmax)   mmax=c[k];
}
}
}
printf("%d\n",mmax);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: