Динамическое программирование


Пример. Пусть X = abcdgh, Y = aedfhr. Наибольшей общей подпоследовательностью будет adh, ее длина равна f(6, 6) = 3



бет3/6
Дата19.07.2016
өлшемі0.53 Mb.
#208895
түріРешение
1   2   3   4   5   6

Пример. Пусть 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  ic, i s. Будем моделировать все возможные переходы Теобальдо, вычисляя значения gok[i], 1  ic, 1  kd. Очевидно, что gok[i] = 1, если существует такое j, что gok-1[j] = 1 и существует ребро из города j в город i. Имея все значения gok[i] (1  ic) для некоторого k (0  kd – 1), вычисляем все значения gok+1[i], 1  ic. Теобальдо может совершить переход из города s в город e за d дней, если god[e] = 1.



Пример. Рассмотрим данные первого теста. Теобальдо следует перейти из города s = 3 в город e = 1 за d = 2 дня. Симметрическая матрица переходов m имеет вид:

m =


Достарыңызбен бөлісу:
1   2   3   4   5   6




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет