【最大子矩阵和】HDU1559-最大子矩阵

最大子矩阵

Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2895    Accepted Submission(s): 1451

Problem Description

给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大。

 

 

Input

输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为四个正整数m,n,x,y(0<m,n<1000
AND 0<x<=m AND 0<y<=n),表示给定的矩形有m行n列。接下来这个矩阵,有m行,每行有n个不大于1000的正整数。

 

 

Output

对于每组数据,输出一个整数,表示子矩阵的最大和。

 

 

Sample Input

1

4 5 2 2

3 361 649 676 588

992 762 156 993 169

662 34 638 89 543

525 165 254 809 280

 

 

Sample Output

2474

 

 

Author

lwg

 

 

Source

HDU
2006-12 Programming Contest

 

 

 

思路:动态规划

状态dp[i][j]代表长i宽j的矩阵的元素和。

(dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1])

假设要求找出x长y宽的最大子矩阵

在i>=x且j>=y的矩阵中找的话,

dp[i][j]就是包含a[i][j]元素的子矩阵的元素和,

则dp[i][j]-dp[i][j-y]-dp[i-x][j]+dp[i-x][j-y]就是

dp[i][j]中x长y宽的子矩阵的元素和(右下角元素为a[i][j])

 

假设在a[5][4]矩阵中求dp[4][3]中长2宽2的子矩阵的元素和(仅仅求元素和,不是最大)

(我们只要求每次求出右下角的子矩阵即可,随着矩阵扩大,答案就会被推算出来)

 

过程:

开始:

dp[4][3]代表的和

dp[4][1]代表的和

dp[2][3]代表的和

dp[2][1]代表的和

算出dp[4][3]中右下角长2宽2的子矩阵的元素和:

 

 

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define max(a,b) (a>b?a:b)
using namespace std;
int dp[1100][1100];
int MAX;
int main()
{
    int i,j,n,m,T,x,y;
    scanf("%d",&T);
    while(T--)
    {
       scanf("%d %d %d %d",&n,&m,&x,&y);
       MAX=0;
       memset(dp,0,sizeof(dp));
       for(i=1;i<=n;i++)
         for(j=1;j<=m;j++)
         {
              scanf("%d",&dp[i][j]);
              dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
              if(i>=x&&j>=y)
              {
                 MAX=max(MAX,dp[i][j]-dp[i][j-y]-dp[i-x][j]+dp[i-x][j-y]);
              }
         }
       printf("%d\n",MAX);
    }
    return 0;
}
时间: 2024-10-02 19:06:46

【最大子矩阵和】HDU1559-最大子矩阵的相关文章

【最大子矩阵和】HDU1081-To The Max

To The Max Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8193    Accepted Submission(s): 3981 Problem Description Given a two-dimensional array of positive and negative integers, a sub-rectan

矩阵的乘法算法

一般矩阵乘法算法: 原理:矩阵相乘最重要的方法是一般矩阵乘积.它只有在第一个矩阵的栏数(column)和第二个矩阵的列数(row)相同时才有定义.一般单指矩阵 乘积时,指的便是一般矩阵乘积.若A为m×n矩阵,B为n×p矩阵,则他们的乘积AB会是一个m×p矩阵.其乘积矩阵的元素如下面式子得出: 代码如下: struct mat{ int n, m; double data[MAXN][MAXN]; }; int mul(mat& c, const mat& a, const mat&

【算法小总结】最大连续子序列和最大连续子矩阵的关系与实现

最大连续子序列和最大连续子矩阵的关系与实现   求最长连续子序列的优化方法(非DP) //求最大连续子序列和与对应的开头元素和结束元素 实现代码: #include<stdio.h> #include<string.h> #include<algorithm> #include<limits.h> #define MAXN 100002 using namespace std; int main() { int i,j,n,a[MAXN],Max,sum,m

poj 1050 最大子矩阵和

一.思路 最大子矩阵和的方法和最大字段和一样 先单独对每行求最大字段和(此时,子矩阵的行为1,就是最大字段和了) 然后,把第i行后的各行对应列的元素加到第i行的对应列元素,每加一行,就求一次最大字段和,这样就把子矩阵的多行压缩为一行了,一行了就是最大字段和了 也可以这样理解: a11 a12 a13 a21 a22 a23 a31 a32 a33 如图,先求第一行最大子段和,再求第一行跟第二行合起来的最大子段和,如a21+a11, a22+a12, a23+a13 的最大子段和,再求第一到第三合

最大子矩阵问题实例解析_C 语言

问题: 求一个M*N的矩阵的最大子矩阵和. 比如在如下这个矩阵中: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 拥有最大和的子矩阵为: 9 2 -4 1 -1 8 其和为15. 思路: 首先,这个子矩阵可以是任意大小的,而且起始点也可以在任何地方,所以,要把最大子矩阵找出来,我们要考虑多种情况. 假定原始矩阵的行数为M,那么对于子矩阵,它的行数可以是1到M的任何一个数,而且,对于一个K行(K < M)的子矩阵,它的第一行可以是原始矩阵的第1行到 M - K +

数组中最大子矩阵,最简便的解法

遇到一个好人,可以改变一生:遇到一本好书,又何尝不是呢? 最近在翻阅 左程云先生的<程序员代码面试指南–IT名企算法与数据结构题目最优解>时就非常的有感悟.建议有这方面爱好的博友,也去观摩观摩. 书中讲解的基于栈的数组的最大矩阵的算法很经典,但是博主能力有限,没能彻底的领悟该算法的精髓,但是根据这个思想,博主想出了一种简易的应对该类问题的算法,现概述如下. 核心思想 先来看一张图吧,我们就可以大致的理解了. 如图,每一个轮次都是一次运算,而我们的核心就是针对这每一个轮次的内部的运算. 计算出每

NYOJ 104(最大子矩阵和)

  此代码在全为-2时,输出0,显然错误,因为函数下标从0开始,而传递的参数希望他从1开始 #include<stdio.h>#include<string.h> int a[101][101],b[10010];int subsequencesum(int a[],int n){ int sum=0,maxsum=0,i; for(i=0;i<n;i++) {  sum+=a[i];  if(sum>maxsum)   maxsum=sum;     else   i

类库与框架,强类型与弱类型的闲聊

    有一天,我问一个同学说,"如果让你通过程序开发一个虚拟地球出来,模拟不同的人的行为,模拟天气,地理,人文,股票涨跌,模拟情感,思考,数学,你怎么做?"那哥们眼睛一亮,马上就说,以人为例.教师,官员,学生,工人都不一样,都从人这个基类继承!天气可以定义一个天气接口,通过工厂模式提供一组天气的集合-       我问,突然哪一天,你需要加一个字段,定义学生是不是程序员!他说,那加一个字段就好了.我说,代码都发布出去了.那哥们开始冥思苦想了.总之你发现,不可能预知未来的需求!人的类型

微软面试题解析:求一个矩阵中最大的二维矩阵(元素和最大)

题目:求一个矩阵中最大的二维矩阵(元素和最大).如: 1 2 0 3 4 2 3 4 5 1 1 1 5 3 0 中最大的是: 4 5 5 3 要求:(1)写出算法;(2)分析时间复杂度;(3)用C写出关键代码 分析: 直接遍历二维数组,求出最大的二维数组就OK了 实现如下: #include<iostream> using namespace std; int max_matrix(int (*array)[5], int maxx, int maxy, int& posi, int