Məsələdə iki sətirin ən uzun ümumi alt ardıcıllığını (ƏUAA) tapmaq və onu çap etmək lazımdır.
massivini quracağıq, burada dp[i][j] x_{[1 \ldots i]} və y_{[1 \ldots j]} sətirlərinin ƏUAA uzunluğuna bərabərdir. dəyəri orijinal sətirlərin ƏUAA uzunluğuna bərabər olacaq (|x| = n, |y| = m).
massivini hesabladıqdan sonra matrisində hüceyrəsindən -a doğru tərs keçərək ƏUAA-nı bərpa edirik. Cari mövqe üçün aşağıdakı addımları yerinə yetiririk:
əgər x_i və y_j simvolları eynidirsə, bu simvol ƏUAA-ya daxil edilməlidir. Onu nəticə sətirinə əlavə edirik və (i - 1, j - 1) hüceyrəsinə keçirik, bu da x_{[1 \ldots i - 1]} və y_{[1 \ldots j - 1]} sətirləri üçün ƏUAA-nı qurmağa davam edir.
əgər x_i və y_j simvolları fərqlidirsə, daha böyük dəyərə sahib olan (i, j - 1) və ya (i - 1, j) hüceyrəsinə keçirik. Əgər dp[i - 1][j] və dp[i][j - 1] hüceyrələrindəki dəyərlər bərabərdirsə, istənilən birinə keçid mümkündür.
Nəticə sətiri və sətirlərinin ən uzun ümumi alt ardıcıllığını özündə saxlayacaq.
Misal
Misalda verilən iki sətir üçün ən uzun ümumi alt ardıcıllığın (ƏUAA) tapılmasını nəzərdən keçirək.
Ümumi alt ardıcıllığın axtarışı (i, j) = (6, 7) mövqeyindən başlayır.
y[6] \ne x[7]: maksimum dəyərə sahib qonşu hüceyrələrdən birinə keçirik, məsələn, .
y[5] \ne x[7]: -ya keçirik.
y[5] = x[6] = '': diaqonal üzrə keçid edirik və '' hərfini ƏUAA-ya daxil edirik.
Alqoritmin reallaşdırılması
Giriş sətirlərini və elan edirik. Onların ƏUAA-nı tapmaq üçün massivindən istifadə edirik.
#define MAX 1001
int dp[MAX][MAX];
string x, y, res;Giriş sətirlərini oxuyuruq və onlara ön tərəfdən boşluq əlavə edirik ki, indeksləşmə -dən başlasın.
cin >> x; n = x.length(); x = " " + x;
cin >> y; m = y.length(); y = " " + y;ƏUAA-nı tapırıq.
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
if (x[i] == y[j])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);sətirində ƏUAA-nı qururuq.
i = n; j = m;
while (i >= 1 && j >= 1)
if (x[i] == y[j])
{
res = res + x[i];
i--; j--;
}
else
{
if (dp[i - 1][j] > dp[i][j - 1])
i--;
else
j--;
}Nəticə sətirini tərs çevirir və çıxışa veririk.
reverse(res.begin(), res.end());
cout << res << endl;