最大子阵

详细思路链接:https://www.cnblogs.com/GodA/p/5237061.html

问题描述:

给定一个n×m 的矩阵A,求A 中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中A 的子矩阵指在A 中行和列均连续的一部分。

输入格式

输入的第一行包含两个整数n,m(1≤n,m≤50),分别表示矩阵 AA 的行数和列数。

接下来n 行,每行m 个整数,表示矩阵Ai,j​(−1000≤Ai,j​≤1000)。

输出格式

输出一行,包含一个整数,表示A 中最大子矩阵的元素和。

样例输入

3 3
2 -4 1
-1 2 1
4 -2 2

样例输出

6


代码:
    /*
    思路剖析: 
    最大子矩阵 
    注意任意行列连续
    就拿3*3矩阵为例
    共有 9 (单个元素)
       +12(两个元素)
       +6 (三个元素)
       +4 (六个元素)
       +1 (九个元素)
       =32种子矩阵模式!
    // 
    此题的关键就是如何选取。
    我们知道矩阵的维数为动态变化过程,但是在挖取子矩阵的过程中,一定是绑定“行”或“列”这个要素。
    //
    具体举例而言:
    对于矩阵 M = {2,-4, 1;
                 -1,2, 1;
             4,-2,2 } 
     单个元素时,我们似乎只要求元素最大值即可;
     非单个元素时,我们会考虑行或者列:
     两个:(2,-4)或(2,-1)等 
     三个:(2,-4,1)或(2,-1,4)等 
     六个:{2,-4,1;-1,2,1}或{2,-4;-1,2;4,-2}等 
     九个:M
    我们发现这样一个规律(行的效果等同于列):
    可以定义出一个值动态变化的三维数组。
    它的三个值分别对应第i行第k列到第j行第k列的元素和(其中i,j,k 均=0,1,2) 
    其中 j 的取值由 i 影响 
     代码细说。 
    */ 
#include <iostream>
#include <cstring>

using namespace std;

int n,m;
int dp[300][300],arr[300];

int MAX(int a[],int n){
    int max=-1000000;
    for(int i=0;i<n;i++){
        int tmpmax=0;
        for(int j=i;j<n;j++){
            tmpmax+=a[j];
        if(tmpmax>max)max=tmpmax;
        }
    }
    return max;
}


int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>dp[i][j];
        }
    }
    int maxsub=-1000000,maxarr=0;
    for(int i=0;i<n;i++)
    {
        memset(arr,0,sizeof(arr));
        for(int j=i;j<n;j++)
        {
            int k;
            for(k=0;k<m;k++)
            {
                arr[k]+=dp[j][k];
            }
            maxarr=MAX(arr,k);/*在这里wa了好几次,第一次是放在该循环的外面了,第二次发现k写成n了,要是写成n计算的数就变多了*/
            if(maxarr>maxsub) maxsub=maxarr;

        }


    }
    cout<<maxsub<<endl;
    return 0;
}

 

posted @ 2018-07-18 21:41  Somnus、M  阅读(220)  评论(0编辑  收藏  举报