最大子矩阵

描述
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是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)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[-127, 127]。
输出
输出最大子矩阵的大小。
样例输入
4
0 -2 -7 0 9 2 -6 2
-4 1 -4  1 -1


8  0 -2
样例输出
15

来源

思路细节:

最简单的想法就是压缩,将二维数组压缩成一维数组,然后在对一维数组里面找其中最大的子序列,就相当于把所有最上的行为u,与最下的行为d的子矩阵的最大和求出!

代码:

#include <bits/stdc++.h>
using namespace std;  
const int MAX = 101;  
int value[MAX][MAX] = {{0,0}};  
int f(int a[], int n)  //找到一维数组中最大子序列 
{  
    int sum = 0, b = 0;  
      
    for(int i=0; i<n; i++)  
    {  
        if(b > 0)  
            b += a[i];  
        else  
            b = a[i];     
        if(b > sum)  
            sum = b;  
    }  
    return sum;  
}     
int maxSum(int n)          
{  
    int sum = 0, max = 0;  
      
    for(int i=0; i<n; i++)  //i控制从第几行开始压缩,每次都是从第i行压缩到最后一行 
    {  
        int b[MAX] = {0};   //i每变化一次,b数组就要重新赋值 
          
        for(int j=i; j<n; j++)  
        {  
            for(int k=0; k<n; k++)  //压缩矩阵 
                b[k] += value[j][k];  
              
            sum = f(b, n);  
              
            if(sum > max)  
                max = sum;    //max存到当前状态,子矩阵的最大值 
        }  
    }   
    return max;     
}  
int main()  
{     
    int n;     
    cin >> n;  
    for(int i=0; i<n; i++)  
    {  
        for(int j=0; j<n; j++)  
            cin >> value[i][j];  
    }  
    cout << maxSum(n); 
    return 0; 
}  

心得:

动态规划的题目,需要将问题进行小化,寻找子问题是解决问题的关键!学会间接解决问题,就比如将数组压缩成一维的,对于我们初学者就比较新鲜,这是解决问题的一个技巧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值