zoukankan      html  css  js  c++  java
  • 动态规划精讲(一)最大子矩阵

    最大子矩阵

    题目:

    给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。

    返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。

    注意:本题相对书上原题稍作改动

    示例:

    输入:
    [
      [-1,0],
      [0,-1]
    ]
    输出:[0,1,0,1]


    思路:

    给定一个正整数和负整数组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。
    返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。

    问题从一维变成了二维,但实质是一样的,同样是再求最大子序和,我们需要将二维转化为一维,对于矩阵的每一列,我们将其加在一起,成为了一维上的一个数,二维矩阵的和转化为了一维数组的和

    代码:

    class Solution {
    public:
        vector<int> getMaxMatrix(vector<vector<int > >& matrix) {
            vector<int> ans(4);//保存最大子矩阵的左上角和右下角的行列坐标
            int N = matrix.size();
            int M = matrix[0].size();
            vector<int> b(M,0);//记录当前i~j行组成大矩阵的每一列的和,将二维转化为一维
            int sum;//相当于dp[i],dp_i
            int maxsum=INT_MIN;//记录最大值
            int bestr1,bestc1;//暂时记录左上角,相当于begin
    
            for(int i=0;i<N;i++){     //以i为上边,从上而下扫描
            
                for(int t=0;t<M;t++ ) b[t]=0;    //每次更换子矩形上边,就要清空b,重新计算每列的和
                
                for(int j=i;j<N;j++){    //子矩阵的下边,从i到N-1,不断增加子矩阵的高
                    //一下就相当于求一次最大子序列和
                    sum = 0;//从头开始求dp
                    for(int k=0;k<M;k++){
                        b[k]+=matrix[j][k];   
    //我们只是不断增加其高,也就是下移矩阵下边,所有这个矩阵每列的和只需要加上新加的哪一行的元素
    //因为我们求dp[i]的时候只需要dp[i-1]和nums[i],所有在我们不断更新b数组时就可以求出当前位置的dp_i
                        if(sum>0){
                            sum+=b[k];
                        }
                        else{
                            sum=b[k];
                            bestr1=i;//自立门户,暂时保存其左上角
                            bestc1=k;
                        }
                        if( sum > maxsum){
                            maxsum = sum;
                            ans[0]=bestr1;//更新答案
                            ans[1]=bestc1;
                            ans[2]=j;
                            ans[3]=k;
                        }
                    }
                }
            }
            //cout<<ans[0]<<"  "<<ans[1]<<"  "<<ans[2]<<"  "<<ans[3];
            return ans;
        }
    };

     

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/13942464.html

  • 相关阅读:
    Codeforces Round #555 (Div. 3) A B C1(很水的题目)
    蓝桥杯国赛之阶乘位数
    POJ-1258 Agri-Net(最小生成树)
    昂贵的聘礼(枚举区间+最短路)
    地斗主(矩阵快速幂)
    救救兔子(二分)
    shell编程之sed编辑器&gawk程序
    typedef&nbsp;struct与struct的区别
    iOS内存管理编程指南
    Object&nbsp;c&nbsp;基础知识
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/13942464.html
Copyright © 2011-2022 走看看