您的位置:首页 > 其它

最大和 NYOJ 简单三维DP

2014-04-04 17:14 190 查看

最大和

描述
给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。 

例子:
0
-2 -7 0 
9
2 -6 2 
-4
1 -4 1 
-1
8 0 -2 
其最大子矩阵为:

9

-4

-1

其元素总和为15。

思路:

    1,预处理每一列的和 sum[i][j] : 第j列从0到第i行的和     e.g.:sum[3][2]=a[1][2]+a[2][2]+a[3][2];

   2 三重循环: 第一重枚举高度从1 到n;

                           第二重枚举一点 (i,j)去计算矩阵  (i-h,,j) 到 (i,j)间的和; 此时就可以当作一维的数组找最大和;

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int pos[110][110];
int dp[110][110][110];
int sum[110][110];
int main()
{

// freopen("in.in","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&pos[i][j]);

for(int j=0;j<=m;j++) pos[0][j]=0;
for(int j=1;j<=m;j++)
for(int i=1;i<=n;i++)
{
sum[i][j]=sum[i-1][j]+pos[i][j];
//   printf("sum[%d][%d]=%d\n",i,j,sum[i][j]);

}

memset(dp,0,sizeof(dp));
int ans=pos[1][1];
for(int h=1;h<=n;h++)
{
for(int i=h;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(dp[h][i][j-1]<=0)
dp[h][i][j]=sum[i][j]-sum[i-h][j];
else dp[h][i][j]=dp[h][i][j-1]+sum[i][j]-sum[i-h][j];
//printf("dp[%d][%d][%d]: %d\n",h,i,j,dp[h][i][j]);
ans=max(ans,dp[h][i][j]);
}
}
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: