最大子矩阵求和 NYOJ 104 && 372 && HDU 1081

链接:click here


给定一个由整数组成二维矩阵(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。

输入
第一行输入一个整数n(0<n<=100),表示有n组测试数据;

每组测试数据:

第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;

随后有r行,每行有c个整数;

输出
输出矩阵的最大子矩阵的元素之和。
样例输入
1
4 4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
样例输出
15

代码:

<span style="font-size:14px;">#include <math.h>
#include <queue>
#include <deque>
#include <vector>
#include <stack>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>
#include <algorithm>

using namespace std;
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
const double eps = 1e-6;
const double Pi = acos(-1.0);
static const int inf= ~0U>>2;
static const int maxn =305;
int map[maxn][maxn],mapp[maxn];
int main()
{
    //freopen("11.txt","r",stdin);
    //freopen("22.txt","w",stdout);
    int n,m,s,k,i,j;
    cin>>n;
    while(n--)
    {
        cin>>m>>s;
        for(i=1; i<=m; i++)
            for(j=1; j<=s; j++)
            {
                cin>>map[i][j];
                map[i][j]+=map[i-1][j];
            }
        int max=map[1][1];
        for(i=0; i<=m-1; i++)
            for(j=i+1; j<=m; j++)
            {
                mem(mapp,0);
                for(k=1; k<=s; k++)
                {
                    if(mapp[k-1]>=0)
                        mapp[k]=mapp[k-1]+map[j][k]-map[i][k];
                    else
                        mapp[k]=map[j][k]-map[i][k];
                    if(max<mapp[k])
                        max=mapp[k];
                }
            }
        cout<<(max)<<endl;
    }
    return 0;
}
</span>
时间: 2024-11-04 21:28:43

最大子矩阵求和 NYOJ 104 && 372 && HDU 1081的相关文章

HDU 1003 &amp;&amp; HDU 1081(最大子列和,最大子矩阵和).

最大子列和,及其扩展最大子矩阵和,都是比较经典的dp,把这两题写在一起,共大家参考学习. ~~~~ lz弱菜啊,到现在还只能写这么水的DP...orz. ~~~~ 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 http://acm.hdu.edu.cn/showproblem.php?pid=1081 题意应该比较好理解,不解释了. 1003: #include<cstdio> #include<iostream> #inc

hdu 1081 &amp; poj 1050 To The Max(最大和的子矩阵)

转载请注明出处:http://blog.csdn.net/u012860063 Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum

hdu 1081最大子矩阵的和DP

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

HDU 1081 To The Max(DP)

题意  求一个n*n矩阵的最大子矩阵和 HDU 1003 max sum 的升级版   把二维简化为一维就可以用1003的方法去做了  用mat[i][j]存  第i行前j个数的和   那么mat[k][j]-mat[k][i]就表示第k行  第i+1个数到第j个数的和了   再将k从一枚举到n就可以得到这个这个宽度为j-i的最大矩阵和了   然后i,j又分别从1枚举到n就能得到结果了   和1003的方法一样  只是多了两层循环 #include<cstdio> #include<cs

hdu--1505--稍微特别的子矩阵求和

这题 是蛮特别的.. 虽然可以将R F转换为 0 1然后求最大子矩阵和 但是这个矩阵中 不能有0 即这个矩阵的元素都是1即F 这题 一开始不会做啊=-= 看了discuss里面的人用了 left 和 right数组 还是一知半解 白痴啊=-= 我把我的理解和porker讲了下 他纠正了我的错误... ------touch  me 我这边将left 和 next 和 height数组简单讲下我的理解 因为我发现 基本上所有人都是没有给出解释的... 假如我们现在要操作第 X 行 的 第 Y 列

hdu 1081

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

杭电2018多校第四场(2018 Multi-University Training Contest 4) 1005.Problem E. Matrix from Arrays (HDU6336) -子矩阵求和-规律+二维前缀和

6336.Problem E. Matrix from Arrays 不想解释了,直接官方题解: 队友写了博客,我是水的他的代码 ------>HDU 6336 子矩阵求和 至于为什么是4倍的,因为这个矩阵是左上半边有数,所以开4倍才能保证求的矩阵区域里面有数,就是图上的红色阴影部分,蓝色为待求解矩阵. 其他的就是容斥原理用一下,其他的就没什么了. 代码: 1 //1005-6336-矩阵求和-二维前缀和+容斥-预处理O(1)查询输出 2 #include<iostream> 3 #in

hihoCoder [Offer收割]编程练习赛3 D子矩阵求和

子矩阵求和 http://hihocoder.com/discuss/question/3005 声明一下: n是和x一起的,m是和y一起的 x是横着的,y是纵着的,x往右为正,y往下为正 (非常反常规的定义) 性质好题 看起来无从下手. 两个关键性质: 证明挺显然的.画画图 同余方程exgcd即可 子矩阵和? 先算出(0,0)的,每次平移,加减一行一列前n或m个, 细节: 1.纵向要循环到n,横向循环到m 2.注意开long long 3.反常规的设定真讨厌 #include<bits/std

HDU 1081 To The Max--DP--(最大子矩阵)

题意:输入一个二维数组,求和最大的子矩阵 分析:一看到和最大的子XX,我就联想到和最大子序列,只不过那是一维这是二维,所以做法都差不多.把二维压缩成一维:你想啊一个矩阵的和不是可以先垂直方向相加把所有行压缩为一行然后这一行相加嘛.压缩过后找最大和的方法跟一维一模一样.但我自己做的时候写了四个循环,唉.....数组可以存放之前求过的和,那么求以下一行为结尾的和的时候只要在原来的数组上加这一行的数就行了,不需要从头循环求和! dp[k]=a[i][k]+.....+a[j][k] 第 k 列第 i