Пример. Пусть X = abcdgh, Y = aedfhr. Наибольшей общей подпоследовательностью будет adh, ее длина равна f(6, 6) = 3. -
c
|
X
|
a
|
b
|
c
|
d
|
g
|
h
|
0
|
1
|
2
|
3
|
4
|
5
|
6
|
Y
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
a
|
1
|
0
|
1 (a)
|
1
|
1
|
1
|
1
|
1
|
e
|
2
|
0
|
1
|
1
|
1
|
1
|
1
|
1
|
d
|
3
|
0
|
1
|
1
|
1
|
2 (d)
|
2
|
2
|
f
|
4
|
0
|
1
|
1
|
1
|
2
|
2
|
2
|
h
|
5
|
0
|
1
|
1
|
1
|
2
|
2
|
3 (h)
|
r
|
6
|
0
|
1
|
1
|
1
|
2
|
2
|
3
|
Реализация. Определим функцию max, вычисляющую максимум двух чисел:
int max(int i,int j)
{
return (i > j) ? i : j;
}
Массивы x и y содержат входные последовательности, lenx и leny – их длины. Массив m содержит две последние строки динамического преобразования.
char x[1001], y[1001];
int m[2][1001];
int lenx, leny;
Входные данные обрабатываем, пока не встретится конец файла. Читаем две входные последовательности в массивы x и y. При этом значения x[0] и y[0] обнуляем, а входные строки заносим в массивы, начиная с первой ячейки. Длины последовательностей сохраняем в переменных lenx и leny.
x[0] = y[0] = 0;
while(gets(x+1),gets(y+1))
{
lenx = strlen(x+1); leny = strlen(y+1);
Обнуляем массив m. Динамически вычисляем значения f(i, j). Изначально m[0][j] содержит значения f(0, j). Далее в m[1][j] заносим значения f(1, j). Поскольку для вычисления f(2, j) достаточно иметь значения двух предыдущих строк массива m, то значения f(2, j) можно сохранять в ячейках m[0][j], значения f(3, j) – в ячейках m[1][j] и так далее.
memset(m,0,sizeof(m));
for(i = 1; i <= lenx; i++)
for(j = 1; j <= leny; j++)
if (x[i] == y[j]) m[i % 2][j] = 1 + m[(i-1)%2][j-1];
else m[i % 2][j] = max(m[(i-1)%2][j],m[i%2][j-1]);
В конце алгоритма длина наибольшей общей подпоследовательности будет находиться в ячейке m[lenx%2][leny]. Выводим ее.
printf("%d\n",m[lenx%2][leny]);
}
6. Путешествие Теобальдо [Вальядолид, 10681]. Пусть gok[i] = 1, если Теобальдо может попасть из начального города s в город i за k переходов, иначе gok[i] = 0. Изначально go0[s] = 1, go0[i] = 0, 1 i c, i s. Будем моделировать все возможные переходы Теобальдо, вычисляя значения gok[i], 1 i c, 1 k d. Очевидно, что gok[i] = 1, если существует такое j, что gok-1[j] = 1 и существует ребро из города j в город i. Имея все значения gok[i] (1 i c) для некоторого k (0 k d – 1), вычисляем все значения gok+1[i], 1 i c. Теобальдо может совершить переход из города s в город e за d дней, если god[e] = 1.
Пример. Рассмотрим данные первого теста. Теобальдо следует перейти из города s = 3 в город e = 1 за d = 2 дня. Симметрическая матрица переходов m имеет вид:
m =
Достарыңызбен бөлісу: |