动态规划:最大子矩阵和

问题描述:

给定一个m*n (0<m, n<=1000)的矩阵,请找到此矩阵的一个连续子矩阵,并且此子矩阵的各个元素的和最大,输出这个最大的值。

 

测试样例:

输入

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

 

算法思路:

动态规划。本题为最大连续子段和的二维推广。注意到,当找到最大子矩阵时,把该子矩阵每列相加得到了一个行数组,在所有可能的这样的行数组中,此行数组的和是最大的!!!这就给我们启发,把所有可能的行数组表示出来,得到行数组后,接下来就是一个一维的最大连续子段和问题,通过比较找到一个最大的连续子段和即可。

 

C++程序:

#include <iostream>
#include <stdio.h>
using namespace std;

//动态规划:以终点为变量
int MIS_Dynamic(int *seq, int n)
{
    int now_sum = seq[0];
    int max_sum = now_sum;
    for(int i=1;i<n; i++){
        now_sum > 0 ? now_sum += seq[i] : now_sum = seq[i];
        if( max_sum < now_sum )
            max_sum = now_sum; 
    }
    return max_sum;
}


int main()
{
    int row, col, tmp, max_sum;
    scanf("%d %d", &row, &col);
    int **mat = new int*[row];
    for(int i=0; i<row; i++){
        mat[i] = new int[col];
        for(int j=0; j<col; j++){
            scanf("%d", &(mat[i][j]));
        }
    }

    int* arr = new int[col];
    for(int i1=0; i1<row; i1++){
        for(int j=0; j<col; j++)  arr[j] = 0;
        for(int i2=i1; i2<row; i2++){
            for(int j=0; j<col; j++)  arr[j] += mat[i2][j];
            tmp = MIS_Dynamic(arr, col);
            if(i1 == 0 && i2 == 0){  //第一次初始赋值
                max_sum = tmp;
            }
            if(max_sum < tmp){
                max_sum = tmp;
            }
        }
    }

    printf("%d \n", max_sum);

    delete[] arr;
    for(int i=0; i<row; i++) delete[] mat[i];\
    delete[] mat;
    return 0;
}

 

posted @ 2017-08-23 11:19  hedgehog小子  阅读(940)  评论(0)    收藏  举报