Aquí está mi línea de recorrido a toda prueba por línea ya que esto es muy común y la mayoría de las veces la gente a explicar la dinámica programación parte 70% y detenerse en los detalles sangrientos.
1) Optimal Subestructura: Vamos X[0..n-1]
ser la secuencia de entrada de longitud n y L(0, n-1)
ser la longitud de la subsecuencia palindrómica más largo de X[0..n-1].
Si últimos y primeros caracteres de X son los mismos, entonces L(0, n-1) = L(1, n-2) + 2
. Espera por qué, ¿qué pasa si el segundo y el segundo al último caracteres no son lo mismo, no sería el último y el primer bing el mismo ser inútil. no, esta "subsecuencia" no tiene que ser continua.
/* Driver program to test above functions */
int main()
{
char seq[] = "panamamanap";
int n = strlen(seq);
printf ("The lnegth of the LPS is %d", lps(seq, 0, n-1));
getchar();
return 0;
}
int lps(char *seq, int i, int j)
{
// Base Case 1: If there is only 1 character
if (i == j)
return 1;
// Base Case 2: If there are only 2 characters and both are same
if (seq[i] == seq[j] && i + 1 == j)
return 2;
// If the first and last characters match
if (seq[i] == seq[j])
return lps (seq, i+1, j-1) + 2;
// If the first and last characters do not match
else return max(lps(seq, i, j-1), lps(seq, i+1, j));
}
Teniendo en cuenta la implementación anterior, siguiente es un árbol de recursión parcial para una secuencia de longitud 6 con todos los caracteres diferentes.
L(0, 5)
/ \
/ \
L(1,5) L(0,4)
/ \ / \
/ \ / \
L(2,5) L(1,4) L(1,4) L(0,3)
En el árbol de recursión parcial anteriormente, L(1, 4)
se está resolviendo dos veces. Si dibujamos el árbol de recursión completo, entonces podemos ver que hay muchos subproblemas que se resuelven una y otra vez. Al igual que otros problemas típicos de Programación Dinámica (DP), se pueden evitar los recuentos de los mismos subproblemas construyendo una matriz temporal L[][]
de abajo hacia arriba.
// Devuelve la longitud de la subsecuencia palindrómica más larga en la SEC
int lps(char *str)
{
int n = strlen(str);
int i, j, cl;
int L[n][n]; // Create a table to store results of subproblems
// Strings of length 1 are palindrome of length 1
for (i = 0; i < n; i++)
L[i][i] = 1;
for (cl=2; cl<=n; cl++) //again this is the length of chain we are considering
{
for (i=0; i<n-cl+1; i++) //start at i
{
j = i+cl-1; //end at j
if (str[i] == str[j] && cl == 2) //if only 2 characters and they are the same then set L[i][j] = 2
L[i][j] = 2;
else if (str[i] == str[j]) //if greater than length 2 and first and last characters match, add 2 to the calculated value of the center stripped of both ends
L[i][j] = L[i+1][j-1] + 2;
else
L[i][j] = max(L[i][j-1], L[i+1][j]); //if not match, then take max of 2 possibilities
}
}
return L[0][n-1];
}
por lo que este es igual que la programación dinámica no lógicamente, es sólo que aquí nos guardar el resultado en una matriz por lo que no calculamos lo mismo una y otra vez
¿Qué tiene esto que ver con los palíndromos? –
Ah, ya veo, el LCPS es "afcfa", no "afca". –
pregunta de programación dinámica. por favor, mire w.r.t DP –