Java动态规划算法:最大子阵

历届试题 最大子阵
问题描述
给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。
其中,A的子矩阵指在A中行和列均连续的一块。

输入格式
输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。

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

样例输入:
3 3
-1 -4 3
3 4 -1
-5 -2 8

样例输出:10

样例说明
取最后一列,和为10。

数据规模和约定
对于50%的数据,1<=n, m<=50;
对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。

思路:求出每一列的前缀和,用于求i层到j层的纵向序列和,再求最大横向子序列和,形成最大子阵和

import java.util.Scanner;

public class Main4 {
    
    

	static int[][] map;
	static int[][] cmap;
	static int[] rmap;

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		map = new int[n + 1][m + 1];
		cmap = new int[n + 1][m + 1];
		rmap = new int[m + 1];
		int ans = Integer.MIN_VALUE;

		for (int i = 1; i <= n; i++) {
    
    
			for (int j = 1; j <= m; j++) {
    
    
				map[i][j] = sc.nextInt();
				// 前缀和
				cmap[i][j] = cmap[i - 1][j] + map[i][j];
			}
		}

		for (int i = 0; i <= n; i++) {
    
    
			for (int j = i + 1; j <= n; j++) {
    
    
				for (int k = 1; k <= m; k++) {
    
    
					// i层到j层的纵向和
					rmap[k] = cmap[j][k] - cmap[i][k];
				}
				// 求横向最大子序列和
				for (int k = 1; k <= m; k++) {
    
    
					if (rmap[k - 1] > 0)
						rmap[k] += rmap[k - 1];
					if (rmap[k] > ans)
						ans = rmap[k];
				}
			}
		}
		System.out.println(ans);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_43610675/article/details/109053500