prefacio
Problemas como la programación dinámica siempre han sido uno de los problemas más difíciles que todos encuentran en el aprendizaje de algoritmos. Una clase de problemas es lineal, también llamada DP lineal. Hoy, analicemos la subsecuencia ascendente más larga I.
información del tema
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
Nota: El requisito de la subsecuencia aquí es estrictamente monótonamente creciente. Por ejemplo 1, 2, 3, 4. No puede ser 1, 1, 2, 3, 4.
formato de entrada
第一行包含整数 N。
第二行包含 N 个整数,表示完整序列。
formato de salida
输出一个整数,表示最大长度。
rango de datos
Rango de datos de esta pregunta:
1≤N≤100000, −109≤数列中的数≤109
el objetivo principal de la pregunta del algoritmo es optimizar la complejidad temporal del algoritmo con la premisa de que se puede hacer, por lo que el rango de datos de la pregunta es un punto que necesita atención.
Muestra
ingresar:
7 3 1 2 1 8 5 6
producción:
4
ideas
El autor de la idea de análisis original: Yan Xuecan. Sitio webAcWing
Puede haber una sola imagen que no entiendo muy bien. Dejame darte un ejemplo.
3 1 2 1 8 5 6
Explicación:
集合:
El conjunto representado por el estado significa el conjunto que termina con un cierto número. Por ejemplo, el conjunto de números 8 incluye, {1,8}, {3,8}, {2,8}, {1,8};
属性:
Pero f[i] es un valor concreto. Este valor representa la longitud de conjunto más larga entre estos conjuntos. Aquí hay 2.
状态计算:
Dado que cada conjunto termina con el i-ésimo número, significa que cada número contiene el número i. La elipse de abajo representa la división de estos conjuntos en clases en el número i-1.
El primer tipo: el número i-1 es 0, es decir, la longitud de la subsecuencia es 1, y no tiene el número i-1
. El segundo tipo: el número i-1 es 1, y su subsecuencia ascendente más larga La longitud de la secuencia es i-1+ i, es decir, f[1]+1
El tercer tipo: el i-2º número es 2, y la longitud de su subsecuencia ascendente más larga es i-2+ i , es decir, f[2 ]+1
...
i-1th: el número i-1th es i-1, y la longitud de su subsecuencia ascendente más larga es i-1+ 1, es decir, f[i-1 ]+1
Cabe señalar que estas secuencias no necesariamente existen, porque es la subsecuencia ascendente más larga, por lo que también debe cumplirse, a[i]>a[j]. Como i es el último número, j debe ser menor que él.
Bueno, después de pensarlo, puedes comenzar a escribir código.
código
import java.util.Scanner;
public class Main {
static int N=1010;
//题目给的子序列
static int a[]=new int[N];
//状态表示的数组
static int f[]=new int[N];
public static void main (String[] args) {
Scanner sc=new Scanner (System.in);
int n=sc.nextInt ();
for (int i = 1 ; i <=n ; i++) {
a[i]=sc.nextInt ();
}
//f[i]表示最长上升子序列的最大长度
for (int i = 1 ; i <=n ; i++) {
f[i]=1;
//f[i]=1 这时只有i一个数,所以f[1]=1;
for (int j = 1 ; j <i ; j++) {
if(a[j]<a[i]){
f[i]=Math.max (f[i],f[j]+1);
}
}
}
//求出所有f的集合后,在遍历一遍f,求出最长的子序列的长度。
int res=0;
for (int i = 1 ; i <=n ; i++) {
res=Math.max (res,f[i]);
}
System.out.println (res);
}
}