Comprensión avanzada de la programación dinámica.

En los últimos tres días, he hecho varios problemas de programación dinámica. A diferencia del pasado, estas transiciones de estado de programación dinámica no son particularmente fáciles de encontrar. El uso de la recursión y los tiempos de espera es realmente un dolor de cabeza. Permítanme enumerar los problemas primero.

Primero, déjenme hablar sobre por qué elegimos la programación dinámica cuando resolvimos este problema. Además de los problemas obvios (es decir, la programación dinámica), generalmente encontramos que algunos problemas son muy independientes, sin atraso y reenvío, es decir, nuestros problemas pueden resolverse por separado, como esta pregunta, Estamos buscando sub-matrices. Las agregamos en el frente y las separamos. Descubrimos que los valores de la matriz posterior no tienen nada que ver con el frente, por lo que podemos considerar el uso de programación dinámica. ¡También podemos usar la recursión, aunque mantengo el tiempo de espera! ! ! (Pero se puede agregar memoria ❀, no he memorizado esta pregunta ~) Después de encontrar el método, consideramos que cada subconjunto se puede dividir 1 a m veces, sin considerar primero si el conjunto dividido por el subconjunto será Más allá de m, encontraremos que la matriz detrás de nosotros está determinada por el número de divisiones y el valor máximo de la división frente a la matriz, lo que también significa que enumeramos una expresión dp [i] [j] [k] (i es la posición que alcanzamos, j es Hacemos un bucle para encontrar la posición del valor máximo más pequeño, k es el número de veces) Cuando resolvemos dp [i] [j] [m], encontramos que no necesitamos enumerar j, porque solo necesitamos obtener el valor máximo más pequeño de 0 a i al final Esta bien Por lo tanto, la ecuación es dp [i] [j] = Math.min (dp [i] [j], dp [j] [k-1] + i posición al valor total de la posición j). A continuación enumeramos el código:

    public int splitArray(int[] nums, int m) {
        int n = nums.length;
        int[][] f = new int[n + 1][m + 1];
        int[] sub = new int[n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                f[i][j] = Integer.MAX_VALUE;
            }
        }
        for (int i = 0; i < n; i++) {
            sub[i + 1] = sub[i] + nums[i];
        }
        f[0][0] = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                for (int k = 0; k < i; k++) {
                    f[i][j] = Math.min(f[i][j], Math.max(f[k][j - 1], sub[i] - sub[k]));
                }
            }
        }
        return f[n][m];        
    }

Solo recuerde tratar el problema crítico.

La segunda pregunta también es mareada. Simplemente me acerqué al borde y no pude encontrar un avance. Esto también me recordó que cuando buscamos ecuaciones dinámicas, no es necesariamente que nuestro estado en este momento esté relacionado con el estado anterior. , También puede formar una ecuación de transición de estado con cualquier estado anterior, a continuación se enumeran los temas:

¡Nuestro problema es encontrar el estado en este momento, pero nuestro último estado es el estado adyacente a este tiempo, no el último estado normal! ¡Así que ten cuidado! A continuación enumeramos el código:

    public int videoStitching111(int[][] clips, int T) {
        int[] dp=new int[T+1];
        Arrays.fill(dp,T);
        dp[0]=0;
        for(int i=1;i<=T;i++){
            for(int[] clip:clips){
                if(i>=clip[0]&&i<=clip[1]){
                    dp[i]=Math.min(dp[i],dp[clip[0]]+1);
                }
            }
        }
        return dp[T]==T?-1:dp[T];
    }

 

17 artículos originales publicados · elogiados 0 · visitas 141

Supongo que te gusta

Origin blog.csdn.net/qq_33286699/article/details/105656241
Recomendado
Clasificación