最大和 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
2
-4
1
-1
8
其元素总和为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; }
相关文章推荐
- 简单DP【p2642】双子序列最大和
- nyoj--325--zb的生日(简单dp)
- BestCoder Round #86 HDU 5804(暴力),HDU 5805(前缀和后缀差值最大),HDU 5806(尺取法),HDU 5807(简单DAG 分步式DP )
- NYOJ995硬币找零(简单dp)
- nyoj--325--zb的生日(简单dp)
- NYOJ 1204 魔法少女 简单DP
- 【简单DP】POJ 1050 最大子矩阵
- hdu 1559(简单的dp)最大子矩阵
- 51Nod 1049 最大子段和(简单DP)
- nyoj 104 最大和 【区间dp】
- nyoj 171 聪明的kk【二维dp&&求最大值】
- codevs1169传纸条 不相交路径取最大,四维转三维DP
- 51nod1270 数组的最大代价(简单dp)
- 括号匹配(二)NYOJ15(简单区间dp)
- DP之简单的求最大字段和问题
- hdu 1003 hdu1231 简单dp最大子串和
- NYOJ27水池数目,类似于FZU1008最大黑区域,简单搜索题~~~
- 简单的dp@poj(2)2479最大子段和
- NYOJ 746 - 正整数n划分为m段,求m段的最大乘积 【区间DP】
- nyoj 44 子串和 【简单dp】