Algoritmo de programación dinámica de Java: el subarreglo más grande

La submatriz más grande de las preguntas de prueba anteriores
Descripción del problema
Dada una matriz A de n * m, encuentre una submatriz no vacía en A para maximizar la suma de los elementos en esta submatriz.
Entre ellos, la submatriz de A se refiere a un bloque en A cuyas filas y columnas son continuas.

Formato de entrada
La primera línea de entrada contiene dos números enteros n, m, que representan el número de filas y columnas de la matriz A, respectivamente.
Las siguientes n filas, cada fila de m enteros, representan la matriz A.

Formato de
salida Muestra una fila, que contiene un número entero, que representa la suma de los elementos en la submatriz más grande en A.

Entrada de muestra:
3 3
-1 -4 3
3 4
-1-5-2 8

Salida de muestra: 10

Descripción de la muestra
Tome la última columna y la suma es 10.

Escala de datos y convenciones
Para el 50% de los datos, 1 <= n, m <= 50;
para el 100% de los datos, 1 <= n, m <= 500, el valor absoluto de cada elemento en A no excede 5000 .

Idea: Encuentre la suma del prefijo de cada columna, usada para encontrar la suma de la secuencia vertical desde la capa i a la capa j, y luego encuentre la suma de subsecuencia horizontal más grande para formar la suma de subarreglo más grande

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);
	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_43610675/article/details/109053500
Recomendado
Clasificación