[C ++] planificación dinámica del día 14 del entrenamiento de verano de henuACM

El código de la programación dinámica es muy corto, pero es difícil pensar en él. Es principalmente necesario encontrar la fórmula de estado y transición de estado. La complejidad del tiempo es O (n ^ 2), no hay mucho que decir, veamos el tema primero.

A 题 Subsecuencia común (HDU 1159)

tema

Una subsecuencia de una secuencia dada es la secuencia dada con algunos elementos (posiblemente ninguno) omitidos. Dada una secuencia X = <x1, x2,…, xm> otra secuencia Z = <z1, z2,…, zk> es una subsecuencia de X si existe una secuencia estrictamente creciente <i1, i2,…, ik> de índices de X tal que para todo j = 1,2,…, k, xij = zj. Por ejemplo, Z = <a, b, f, c> es una subsecuencia de X = <a, b, c, f, b, c> con secuencia de índice <1, 2, 4, 6>. Dadas dos secuencias X e Y, el problema es encontrar la longitud de la subsecuencia común de longitud máxima de X e Y.
La entrada del programa es de un archivo de texto. Cada conjunto de datos del archivo contiene dos cadenas que representan las secuencias dadas. Las secuencias están separadas por cualquier número de espacios en blanco. Los datos de entrada son correctos. Para cada conjunto de datos, el programa imprime en la salida estándar la longitud de la subsecuencia común de longitud máxima desde el comienzo de una línea separada.

Entrada

abcfbc
concurso de programación
abfcab abcd mnp

Salida

4
2
0

Título

Es encontrar la subsecuencia común más larga (LCS)

Ideas

De hecho, se encuentran disponibles matrices unidimensionales y bidimensionales.
Estado unidimensional: dp [i, j] representa la
transición de estado de la longitud de LCS que termina en a [i], b [j] : cuando a [i] = b [j] , Dp [i, j] = dp [i-1, j-1] +1.
De lo contrario: dp [i, j] = max (dp [i -1, j], dp [i] [j -1 ])
Inserte la descripción de la imagen aquí
(Red de fuente de imagen)

En el código:

#include <iostream>
#include <string.h>
using namespace std;
const int maxx= 999;
int dp[maxx][maxx];

int main()
{
    
    
    string s1,s2;
    while(cin>>s1)
    {
    
    
        cin>>s2;
        memset(dp,0,sizeof dp);
        for(int i=0;i<s1.length();++i){
    
    
            for(int j=0;j<s2.length();++j){
    
    
                if(s1[i]==s2[j]){
    
    
                    if(i>0 && j>0){
    
    
                        dp[i][j]=dp[i-1][j-1]+1;
                    }
                    else{
    
    dp[i][j]=1;}
                }
                if(i>0){
    
    
                    dp[i][j]=max(dp[i-1][j],dp[i][j]);
                }
                if(j>0){
    
    
                    dp[i][j]=max(dp[i][j],dp[i][j-1]);
                }
            }
        }
        int ans=0;
        for(int i=0;i<s1.length();++i){
    
    
            for(int j=0;j<s2.length();++j){
    
    
                ans = max(ans,dp[i][j]);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

Pregunta B ¡¡¡Súper salto !!! (HDU 1087)

tema

Hoy en día, una especie de juego de ajedrez llamado “Super Jumping! ¡Saltando! ¡Saltando! " es muy popular en HDU. Quizás eres un buen chico y sabes poco sobre este juego, así que te lo presento ahora.
Inserte la descripción de la imagen aquí
El juego puede ser jugado por dos o más de dos jugadores. Consiste en un tablero de ajedrez (棋盘) y algunas piezas de ajedrez (棋子), y todas las piezas de ajedrez están marcadas con un número entero positivo o “comienzo” o “final”. El jugador comienza desde el punto de inicio y finalmente debe saltar al punto final. En el curso del salto, el jugador visitará las piezas de ajedrez en el camino, pero todos deben saltar de una pieza de ajedrez a otra absolutamente más grande (puede asumir que el punto de inicio es mínimo y el punto final es máximo). Y todos los jugadores no pueden retroceder. Un salto puede pasar de una pieza de ajedrez a la siguiente, también puede atravesar muchas piezas de ajedrez e incluso puedes llegar directamente al punto final desde el punto de inicio. Por supuesto, obtienes cero puntos en esta situación. Un jugador es un ganador si y solo si puede obtener una puntuación mayor de acuerdo con su solución de salto.
Su tarea es generar el valor máximo de acuerdo con la lista de piezas de ajedrez dada.

Entrada

La entrada contiene varios casos de prueba. Cada caso de prueba se describe en una línea de la siguiente manera:
N valor_1 valor_2… valor_N
Se garantiza que N no es más de 1000 y todos los valores_i están en el rango de 32-int.
Un caso de prueba que comienza con 0 termina la entrada y este caso de prueba no se procesará.

Salida

Para cada caso, imprima el máximo según las reglas, y una línea un caso.

Entrada simple

3 1 3 2
4 1 2 3 4
4 3 3 2 1
0

Salida simple

4
10
3

Título

Es encontrar una subsecuencia ascendente con pesos de modo que la suma de los pesos sea la mayor.La diferencia con la subsecuencia ascendente más larga general (LIS) también está aquí.

Ideas

Puede usar directamente dp como la respuesta y luego sumar las respuestas de cada paso

Código

#include <string.h>
#include <iostream>
using namespace std;
int n;
const int maxx=999;
int s[maxx];
int dp[maxx];

int main()
{
    
    
    while(cin>>n && n)
    {
    
    
        int ans =0;
        memset(dp,0,sizeof dp);
        for(int i=0;i<n;++i){
    
    
            cin>>s[i];
        }
        for(int i=0;i<n;++i){
    
    ///     重
                dp[i] = s[i]; ///     点
            for(int j=0;j<i;++j){
    
    ///     在
                if(s[i]>s[j] && dp[i]<dp[j]+s[i]){
    
      /// 这
                    dp[i] = dp[j]+s[i];  ///    里
                }
        }
        }
        for(int i=0;i<n;++i){
    
    
            ans = max(ans,dp[i]);
        }
        cout<<ans<<endl;
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_44899247/article/details/97668321
Recomendado
Clasificación