动态规划:最大子矩阵和
问题描述:
给定一个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; }

浙公网安备 33010602011771号