Problema de planificación dinámica ------- Problema real de la Copa Lanqiao ------- Preparación de la Copa Blue Bridge

Triángulo digital

descripción de la imagen

La figura de arriba muestra un triángulo digital. Hay muchos caminos diferentes desde la parte superior hasta la parte inferior del triángulo. Para cada ruta, sume los números en la ruta para obtener una suma. Su tarea es encontrar la suma más grande.

Cada paso en el camino solo puede ir de un número al número de la izquierda o la derecha del siguiente nivel más cercano a él. Además, la diferencia entre el número de veces que se baja a la izquierda y el número de veces que se baja a la derecha no puede exceder de uno .

Ingrese descripción

La primera línea de entrada contiene un número entero N (1≤ N ≤100), que representa el número de triángulos.

Las siguientes N N líneas dan triángulos digitales. Los números del triángulo digital son todos números enteros entre 0 y 100.

Descripción de salida

Genere un número entero para indicar la respuesta.

Entrada y salida de muestra

Ejemplo

ingresar

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

Producción

27

Restricciones operativas

  • Tiempo máximo de ejecución: 1 s
  • Memoria operativa máxima: 256 M

Si no nos recordamos que usemos la programación dinámica para hacer lo que haríamos al principio, definitivamente podemos pensar en usar una matriz bidimensional para almacenar nuestros triángulos digitales. Para mayor claridad, lo dibujaré de manera más intuitiva. (Representado por un árbol)

Inserte la descripción de la imagen aquí

Ideas

De acuerdo con el significado de la pregunta, vamos a calcular el valor más grande de lo anterior. Al principio, quería usar una matriz auxiliar para almacenar los valores y sumar para ver el más grande, pero eso sería demasiado problemático. Podemos modificar directamente nuestros números. Triángulo para obtener nuestro valor de ruta

La pregunta es, ¿se puede utilizar el algoritmo de rama? Descubrimos que cada paso que damos no es necesariamente el mismo, es decir, cada paso que damos es independiente ¿Quién sabe si ese paso que damos es el mayor valor?

En otras palabras, tenemos que considerar la forma de programación dinámica, nuestro siguiente paso está relacionado con el resultado del paso anterior, se construye sobre la base del paso anterior y se ajusta a nuestra programación dinámica.

Solo puede seguir la siguiente fila de rutas digitales adyacentes. Cada paso es el mismo. Este es el mismo punto. El resultado del siguiente paso se establece en base al resultado del paso anterior. Todos se ajustan a la programación dinámica, así que utilice la programación dinámica

Código

public class 数字三角形 {
    
    
	public static void main(String[] args) {
    
    
		 Scanner scan = new Scanner(System.in);
	     //在此输入您的代码...
		 //1.二维数组来存储我们的三角形
		 //1.1我们的行数
		 int N = scan.nextInt();
		 int[][] arr = new int[N+1][N+1];
		 //1.2生成数字三角形
		 for (int i = 1; i <= N; i++) {
    
    
			for (int j = 1; j <= i; j++) {
    
    
				arr[i][j] = scan.nextInt();
			}
		 }
		 //2.计算我们的最大值
		 for (int i = 1; i <= N; i++) {
    
    
			for (int j = 1; j <= i; j++) {
    
    
				arr[i][j] = arr[i][j] + Math.max(arr[i-1][j], arr[i-1][j-1]);
			}
		}
		 //
		 if(N%2 != 0){
    
    
			 System.out.println(arr[N][N/2+1]);
		 }else{
    
    
	         System.out.println(Math.max(arr[N][N/2+1],arr[N][N/2]));
		 }
	     scan.close();
	}
}

Al principio no sabía cuál era la solución, porque no la había visto antes, así que tuve que depurar paso a paso para entender sus pensamientos. Es fácil de entender con solo hacer un dibujo.

El primer paso :

arr [1] 1 = arr [1] 1 + max [0] [1 no tiene sentido, no tenemos resultados en la primera ronda

Segundo paso

i = 2 j = 1

arr[2][1] = arr[2][1] + Math.max(arr[1][1], arr[1][0]); ==>  10

yo = 2 j = 2

arr[2][2] = arr[2][2] + Math.max(arr[1][2], arr[1][1]);
		  =  8        +       0         7   = 15

Inserte la descripción de la imagen aquí

tercer paso

i = 3 j = 1

arr[3][1] = arr[3][1] + Math.max(arr[2][1], arr[2][0]); ==>
    			8	+		(10,0)     =   18

yo = 3 j = 2

arr[3][2] = arr[3][2] + Math.max(arr[2][2], arr[2][1]); ==>  
     			1    +   (15,10)      =  16

yo = 3 j = 3

arr[3][3] = arr[3][3] + Math.max(arr[2][3], arr[2][2]); ==> 
    			0	+		(0,15)			 =    15

el cuarto paso

Los mismos pasos se vuelven

Inserte la descripción de la imagen aquí

Finalmente se convierte en

Inserte la descripción de la imagen aquí

Tenemos otra pregunta, ¿por qué la respuesta a 27 cuando sabemos que 30 es la mayor

La razón principal es que nuestro problema requiere que la diferencia entre el número de veces que se baja a la izquierda y el número de veces que se baja a la derecha no debe exceder de 1. ¿Cómo entendemos esto?

Mire cómo vino 30.7 3 8 7 5, de los cuales 7 3 8 5 bajaron a la derecha 3 veces, y 7 bajaron a la izquierda solo una vez, lo cual no cumple con el significado de la pregunta, entonces entenderemos, siempre la diferencia no es más de 1, entonces debe ser el valor en el medio por lo que es 27

Supongo que te gusta

Origin blog.csdn.net/qq_22155255/article/details/114481570
Recomendado
Clasificación