代码题(35)— 最大和子矩阵

1、最大和子矩阵

问题:
求一个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 + 1 的任意一行。同时对于每一个得到的子矩阵,假设这个子矩阵是 2 *k, 也就是说它只有两行,要找出最大子矩阵,我们要从左到右不断的遍历才能找出在这种情况下的最大子矩阵。如果我们把这两行上下相加,情况就和求“最大子段和问题” 又是一样的了。

  为了找出在原始矩阵里的最大子矩阵,我们要遍历所有的子矩阵的可能情况,也就是说,我们要考虑这个子矩阵有可能只有1行,2行,。。。到n行。而在每一种情况下,我们都要把它所对应的矩阵部分上下相加才求最大子矩阵(局部)。

class SubMatrix {
public:
    int sumOfSubMatrix(vector<vector<int> > mat, int n) {
        // write code here
        if(mat.empty() || n<=0)
            return 0;
        int maxsum = 0;
        for(int i=0;i<n;++i)
        {
            vector<int> temp(mat[i]);
            maxsum = max(maxsum, subArray(temp));
            for(int j=i+1;j<n;++j)
            {
                for(int k=0;k<n;++k)
                {
                    temp[k] = temp[k] + mat[j][k];
                }
                maxsum = max(maxsum, subArray(temp));
            }
        }
        return maxsum;
    }
    // 一维数组最大自序和
    int subArray(vector<int> &temp)
    {
        int sum = temp[0];
        int maxsum = temp[0];
        for(int i=1;i<temp.size();++i)
        {
            if( sum>=0)
                sum += temp[i];
            else
                sum = temp[i];
            maxsum = max(maxsum, sum);
        }
        return maxsum;
    }
};

原文地址:https://www.cnblogs.com/eilearn/p/9424998.html

时间: 2024-10-12 22:37:13

代码题(35)— 最大和子矩阵的相关文章

NOI题库 1768最大子矩阵 题解

NOI题库 1768最大子矩阵  题解 总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15. 输入   输入是一个N * N的矩阵.输入的第一行给出N (0 < N <= 100).再后面的若干行中,依

HDU 1559 最大子矩阵--dp--(最大和子矩阵模型)

题意:给定一个矩阵,求一个宽为a,长为b的子矩阵的最大和 分析:直接用最大和子矩阵的公式,只是这里多了一个限制条件,所以在求和的时候稍有点不同,就是不逐行和逐列求了而是每次以a,b为跨度来求 dp[k]=mt[i][k]+....+mt[i+a][k],然后每次求sum=dp[k]+.....+dp[k+b],mx=max(mx,sum) 代码: #include<iostream> #include<cstring> using namespace std; int m,n,a,

面试题收集-java面试题及答案(基础题122道,代码题19道)

JAVA相关基础知识1.面向对象的特征有哪些方面?1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二是数据抽象.2.继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类).派

导致程序员写出烂代码的35个恶习,看看你染上了几个?

IT行业的科技公司们一直苦苦追寻传说中以一当十的超级程序员,最新的研究表明确实存在这样一小撮效率奇高的"程序金刚",但是一位普通程序猿如何能够蜕变成代码金刚呢? 国内外的各大专家总结了导致程序猿效率低下,代码为什么像坨shi一,样难以维护的35条恶习(归为代码组织.团队工作.写代码.测试与维护四大类). 代码组织 1.总是说"一会弄好",但从来不兑现.(缺乏任务管理和时间管理能力) 2.坚持所谓的高效.优雅的"一行代码流",事实上,可读性才是最重

Java面试题及答案(基础题122道,代码题19道)

转载自:http://www.blogjava.net/fanyingjie/archive/2007/06/27/126467.aspx JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二是数据抽象.2.继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的

java常见面试题及答案(基础题122道,代码题19道)

JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二是数据抽象.2.继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类).派

java面试题及答案(基础题122道,代码题19道)(转)

JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二是数据抽象. 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父

ZOJ1074 (最大和子矩阵 DP)

F - 最大子矩阵和 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u 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

iOS中书写代码规范35条小建议

1.精简代码, 返回最后一句的值,这个方法有一个优点,所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染.但缺点是可读性比较差 NSURL *url = ({ NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint]; [NSURL URLWithString:urlString]; }); 2.关于编译器:关闭警告: #pragma