Ecco la mia linea di walkthrough infallibile per riga dal momento che questo è abbastanza comune e la maggior parte delle volte le persone a spiegare la dinamica programmare la parte 70% e fermarsi ai dettagli sanguinosi.
1) ottimale Sottostruttura: Sia X[0..n-1]
tramite la sequenza di input di lunghezza n e L(0, n-1)
essere la lunghezza della più lunga sottosequenza palindromo di X[0..n-1].
Se ultimi e primi caratteri di X sono uguali, allora L(0, n-1) = L(1, n-2) + 2
. aspetta perché, e se il secondo e il penultimo carattere non sono lo uguali, non sarebbe l'ultimo e il primo bing lo stesso essere inutile. No, questa "sottosuccessione" non deve essere 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));
}
Considerando quanto sopra attuazione, seguito è un albero ricorsione parziale per una sequenza di lunghezza 6 con tutti i caratteri diversi.
L(0, 5)
/ \
/ \
L(1,5) L(0,4)
/ \ / \
/ \ / \
L(2,5) L(1,4) L(1,4) L(0,3)
Nella suddetta albero di ricorsione parziale, L(1, 4)
si sta risolvendo due volte. Se disegniamo l'albero di ricorsione completo, possiamo vedere che ci sono molti sottoproblemi che vengono risolti ancora e ancora. Come altri tipici problemi di programmazione dinamica (DP), è possibile evitare ricalcole degli stessi sottoproblemi costruendo un array temporaneo L[][]
in modo ascendente.
// Restituisce la lunghezza della più lunga sottosequenza palindromi in SEQ
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];
}
quindi questo è proprio come la programmazione non dinamica logicamente, è solo qui abbiamo salvare il risultato in un array in modo da non calcoliamo la stessa cosa più e più volte
Cosa c'entra questo con i palindromi? –
Ah, vedo, la LCPS è "afcfa", non "afca". –
domanda di programmazione dinamica. per favore guarda w.r.t DP –