mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-14 16:16:06 +00:00
deploy
This commit is contained in:
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1181,7 +1181,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1203,7 +1203,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1309,7 +1309,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1591,7 +1591,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1613,7 +1613,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1691,7 +1691,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1786,7 +1786,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1808,7 +1808,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1886,7 +1886,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -1970,7 +1970,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2133,7 +2133,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2224,7 +2224,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2246,7 +2246,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2296,7 +2296,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2352,7 +2352,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2491,7 +2491,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2519,7 +2519,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2547,7 +2547,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2575,7 +2575,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2780,7 +2780,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2808,7 +2808,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3113,7 +3113,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3141,7 +3141,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3418,7 +3418,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3561,7 +3561,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3673,7 +3673,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4377,7 +4377,7 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="146">14.6 Задача о расстоянии редактирования<a class="headerlink" href="#146" title="Permanent link">¶</a></h1>
|
||||
<p>Расстояние редактирования, также называемое расстоянием Левенштейна, обозначает минимальное число правок, необходимых для взаимного преобразования двух строк. Обычно оно используется для измерения сходства двух последовательностей в информационном поиске и обработке естественного языка.</p>
|
||||
<p>Расстояние редактирования, также называемое расстоянием Левенштейна, - это минимальное количество изменений, необходимых для преобразования одной строки в другую. Обычно оно используется для измерения сходства двух последовательностей в информационном поиске и обработке естественного языка.</p>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">Question</p>
|
||||
<p>Даны две строки <span class="arithmatex">\(s\)</span> и <span class="arithmatex">\(t\)</span> . Верните минимальное число шагов редактирования, необходимое для преобразования <span class="arithmatex">\(s\)</span> в <span class="arithmatex">\(t\)</span> .</p>
|
||||
@@ -4387,7 +4387,7 @@
|
||||
<p><img alt="Пример данных для задачи о расстоянии редактирования" class="animation-figure" src="../edit_distance_problem.assets/edit_distance_example.png" /></p>
|
||||
<p align="center"> Рисунок 14-27 Пример данных для задачи о расстоянии редактирования </p>
|
||||
|
||||
<p><strong>Задачу о расстоянии редактирования можно очень естественно описать через модель дерева решений</strong>. Строки соответствуют узлам дерева, а один раунд решения (одна операция редактирования) соответствует одному ребру дерева.</p>
|
||||
<p><strong>Задачу о расстоянии редактирования можно естественным образом объяснить с помощью модели дерева решений</strong>. Строки соответствуют узлам дерева, а один шаг решения, то есть одна операция редактирования, соответствует одному ребру дерева.</p>
|
||||
<p>Как показано на рисунке 14-28, если не ограничивать число операций, то каждый узел может порождать множество ребер, и каждое из них соответствует одному из вариантов преобразования. Это означает, что преобразовать <code>hello</code> в <code>algo</code> можно множеством разных путей.</p>
|
||||
<p>С точки зрения дерева решений цель этой задачи - найти кратчайший путь между узлом <code>hello</code> и узлом <code>algo</code> .</p>
|
||||
<p><img alt="Представление задачи о расстоянии редактирования через дерево решений" class="animation-figure" src="../edit_distance_problem.assets/edit_distance_decision_tree.png" /></p>
|
||||
@@ -4401,7 +4401,7 @@
|
||||
<li>Если <span class="arithmatex">\(s[n-1]\)</span> и <span class="arithmatex">\(t[m-1]\)</span> совпадают, их можно просто пропустить и сразу перейти к сравнению <span class="arithmatex">\(s[n-2]\)</span> и <span class="arithmatex">\(t[m-2]\)</span> .</li>
|
||||
<li>Если <span class="arithmatex">\(s[n-1]\)</span> и <span class="arithmatex">\(t[m-1]\)</span> различны, нужно выполнить над <span class="arithmatex">\(s\)</span> одну операцию редактирования (вставку, удаление или замену), чтобы последние символы стали одинаковыми, после чего можно перейти к задаче меньшего размера.</li>
|
||||
</ul>
|
||||
<p>Иначе говоря, каждое решение (операция редактирования), которое мы выполняем над строкой <span class="arithmatex">\(s\)</span> , меняет те символы, которые еще остаются несопоставленными в строках <span class="arithmatex">\(s\)</span> и <span class="arithmatex">\(t\)</span> . Поэтому состояние определяется текущими позициями рассматриваемых символов в <span class="arithmatex">\(s\)</span> и <span class="arithmatex">\(t\)</span> , то есть состоянием <span class="arithmatex">\([i, j]\)</span> .</p>
|
||||
<p>Иначе говоря, каждый шаг решения, то есть операция редактирования над строкой <span class="arithmatex">\(s\)</span> , меняет те символы, которые еще необходимо сопоставить в строках <span class="arithmatex">\(s\)</span> и <span class="arithmatex">\(t\)</span> . Поэтому состояние определяется текущими позициями рассматриваемых символов в <span class="arithmatex">\(s\)</span> и <span class="arithmatex">\(t\)</span> , то есть состоянием <span class="arithmatex">\([i, j]\)</span> .</p>
|
||||
<p>Подзадача, соответствующая состоянию <span class="arithmatex">\([i, j]\)</span> , такова: <strong>минимальное число операций редактирования, необходимое для преобразования первых <span class="arithmatex">\(i\)</span> символов строки <span class="arithmatex">\(s\)</span> в первые <span class="arithmatex">\(j\)</span> символов строки <span class="arithmatex">\(t\)</span></strong>.</p>
|
||||
<p>Отсюда получается двумерная таблица <span class="arithmatex">\(dp\)</span> размера <span class="arithmatex">\((i+1) \times (j+1)\)</span> .</p>
|
||||
<p><strong>Шаг 2: найти оптимальную подструктуру и на ее основе вывести уравнение перехода состояния</strong></p>
|
||||
@@ -4414,7 +4414,7 @@
|
||||
<p><img alt="Переходы состояния в задаче о расстоянии редактирования" class="animation-figure" src="../edit_distance_problem.assets/edit_distance_state_transfer.png" /></p>
|
||||
<p align="center"> Рисунок 14-29 Переходы состояния в задаче о расстоянии редактирования </p>
|
||||
|
||||
<p>Согласно этому анализу оптимальная подструктура такова: минимальное число шагов редактирования для <span class="arithmatex">\(dp[i, j]\)</span> равно минимуму из трех значений - <span class="arithmatex">\(dp[i, j-1]\)</span> , <span class="arithmatex">\(dp[i-1, j]\)</span> и <span class="arithmatex">\(dp[i-1, j-1]\)</span> - плюс цена текущей операции редактирования <span class="arithmatex">\(1\)</span> . Значит, уравнение перехода состояния имеет вид:</p>
|
||||
<p>Согласно этому анализу оптимальная подструктура такова: минимальное число шагов редактирования для <span class="arithmatex">\(dp[i, j]\)</span> равно минимуму из трех значений - <span class="arithmatex">\(dp[i, j-1]\)</span> , <span class="arithmatex">\(dp[i-1, j]\)</span> и <span class="arithmatex">\(dp[i-1, j-1]\)</span> - плюс <span class="arithmatex">\(1\)</span> шаг за текущее редактирование. Значит, уравнение перехода состояния имеет вид:</p>
|
||||
<div class="arithmatex">\[
|
||||
dp[i, j] = \min(dp[i, j-1], dp[i-1, j], dp[i-1, j-1]) + 1
|
||||
\]</div>
|
||||
@@ -4809,7 +4809,7 @@ dp[i, j] = dp[i-1, j-1]
|
||||
<p><div style="height: 549px; width: 100%;"><iframe class="pythontutor-iframe" src="https://pythontutor.com/iframe-embed.html#code=def%20edit_distance_dp%28s%3A%20str%2C%20t%3A%20str%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%D0%A0%D0%B5%D0%B4%D0%B0%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B5%20%D1%80%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5%3A%20%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%22%22%22%0A%20%20%20%20n%2C%20m%20%3D%20len%28s%29%2C%20len%28t%29%0A%20%20%20%20dp%20%3D%20%5B%5B0%5D%20%2A%20%28m%20%2B%201%29%20for%20_%20in%20range%28n%20%2B%201%29%5D%0A%20%20%20%20%23%20%D0%9F%D0%B5%D1%80%D0%B5%D1%85%D0%BE%D0%B4%20%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B9%3A%20%D0%BF%D0%B5%D1%80%D0%B2%D0%B0%D1%8F%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B0%20%D0%B8%20%D0%BF%D0%B5%D1%80%D0%B2%D1%8B%D0%B9%20%D1%81%D1%82%D0%BE%D0%BB%D0%B1%D0%B5%D1%86%0A%20%20%20%20for%20i%20in%20range%281%2C%20n%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20dp%5Bi%5D%5B0%5D%20%3D%20i%0A%20%20%20%20for%20j%20in%20range%281%2C%20m%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20dp%5B0%5D%5Bj%5D%20%3D%20j%0A%20%20%20%20%23%20%D0%9F%D0%B5%D1%80%D0%B5%D1%85%D0%BE%D0%B4%20%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B9%3A%20%D0%BE%D1%81%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8%20%D0%B8%20%D1%81%D1%82%D0%BE%D0%BB%D0%B1%D1%86%D1%8B%0A%20%20%20%20for%20i%20in%20range%281%2C%20n%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20for%20j%20in%20range%281%2C%20m%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20s%5Bi%20-%201%5D%20%3D%3D%20t%5Bj%20-%201%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%D0%95%D1%81%D0%BB%D0%B8%20%D0%B4%D0%B2%D0%B0%20%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%B0%20%D1%80%D0%B0%D0%B2%D0%BD%D1%8B%2C%20%D1%81%D1%80%D0%B0%D0%B7%D1%83%20%D0%BF%D1%80%D0%BE%D0%BF%D1%83%D1%81%D1%82%D0%B8%D1%82%D1%8C%20%D0%B8%D1%85%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dp%5Bi%5D%5Bj%5D%20%3D%20dp%5Bi%20-%201%5D%5Bj%20-%201%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%D0%9C%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5%20%D1%87%D0%B8%D1%81%D0%BB%D0%BE%20%D1%88%D0%B0%D0%B3%D0%BE%D0%B2%20%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%3D%20%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5%20%D1%87%D0%B8%D1%81%D0%BB%D0%BE%20%D1%88%D0%B0%D0%B3%D0%BE%D0%B2%20%D0%B4%D0%BB%D1%8F%20%D0%B2%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B8%2C%20%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%B8%20%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%8B%20%2B%201%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dp%5Bi%5D%5Bj%5D%20%3D%20min%28dp%5Bi%5D%5Bj%20-%201%5D%2C%20dp%5Bi%20-%201%5D%5Bj%5D%2C%20dp%5Bi%20-%201%5D%5Bj%20-%201%5D%29%20%2B%201%0A%20%20%20%20return%20dp%5Bn%5D%5Bm%5D%0A%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20s%20%3D%20%22bag%22%0A%20%20%20%20t%20%3D%20%22pack%22%0A%20%20%20%20n%2C%20m%20%3D%20len%28s%29%2C%20len%28t%29%0A%0A%20%20%20%20%23%20%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%0A%20%20%20%20res%20%3D%20edit_distance_dp%28s%2C%20t%29%0A%20%20%20%20print%28f%22%D0%A7%D1%82%D0%BE%D0%B1%D1%8B%20%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%7Bs%7D%20%D0%B2%20%7Bt%7D%2C%20%D0%BD%D1%83%D0%B6%D0%BD%D0%BE%20%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D1%83%D0%BC%20%7Bres%7D%20%D1%88%D0%B0%D0%B3%D0%BE%D0%B2%22%29&codeDivHeight=472&codeDivWidth=350&cumulative=false&curInstr=6&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe></div>
|
||||
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=def%20edit_distance_dp%28s%3A%20str%2C%20t%3A%20str%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%D0%A0%D0%B5%D0%B4%D0%B0%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B5%20%D1%80%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5%3A%20%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%22%22%22%0A%20%20%20%20n%2C%20m%20%3D%20len%28s%29%2C%20len%28t%29%0A%20%20%20%20dp%20%3D%20%5B%5B0%5D%20%2A%20%28m%20%2B%201%29%20for%20_%20in%20range%28n%20%2B%201%29%5D%0A%20%20%20%20%23%20%D0%9F%D0%B5%D1%80%D0%B5%D1%85%D0%BE%D0%B4%20%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B9%3A%20%D0%BF%D0%B5%D1%80%D0%B2%D0%B0%D1%8F%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B0%20%D0%B8%20%D0%BF%D0%B5%D1%80%D0%B2%D1%8B%D0%B9%20%D1%81%D1%82%D0%BE%D0%BB%D0%B1%D0%B5%D1%86%0A%20%20%20%20for%20i%20in%20range%281%2C%20n%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20dp%5Bi%5D%5B0%5D%20%3D%20i%0A%20%20%20%20for%20j%20in%20range%281%2C%20m%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20dp%5B0%5D%5Bj%5D%20%3D%20j%0A%20%20%20%20%23%20%D0%9F%D0%B5%D1%80%D0%B5%D1%85%D0%BE%D0%B4%20%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B9%3A%20%D0%BE%D1%81%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8%20%D0%B8%20%D1%81%D1%82%D0%BE%D0%BB%D0%B1%D1%86%D1%8B%0A%20%20%20%20for%20i%20in%20range%281%2C%20n%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20for%20j%20in%20range%281%2C%20m%20%2B%201%29%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20s%5Bi%20-%201%5D%20%3D%3D%20t%5Bj%20-%201%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%D0%95%D1%81%D0%BB%D0%B8%20%D0%B4%D0%B2%D0%B0%20%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%B0%20%D1%80%D0%B0%D0%B2%D0%BD%D1%8B%2C%20%D1%81%D1%80%D0%B0%D0%B7%D1%83%20%D0%BF%D1%80%D0%BE%D0%BF%D1%83%D1%81%D1%82%D0%B8%D1%82%D1%8C%20%D0%B8%D1%85%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dp%5Bi%5D%5Bj%5D%20%3D%20dp%5Bi%20-%201%5D%5Bj%20-%201%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%D0%9C%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5%20%D1%87%D0%B8%D1%81%D0%BB%D0%BE%20%D1%88%D0%B0%D0%B3%D0%BE%D0%B2%20%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%3D%20%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5%20%D1%87%D0%B8%D1%81%D0%BB%D0%BE%20%D1%88%D0%B0%D0%B3%D0%BE%D0%B2%20%D0%B4%D0%BB%D1%8F%20%D0%B2%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B8%2C%20%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%B8%20%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D1%8B%20%2B%201%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dp%5Bi%5D%5Bj%5D%20%3D%20min%28dp%5Bi%5D%5Bj%20-%201%5D%2C%20dp%5Bi%20-%201%5D%5Bj%5D%2C%20dp%5Bi%20-%201%5D%5Bj%20-%201%5D%29%20%2B%201%0A%20%20%20%20return%20dp%5Bn%5D%5Bm%5D%0A%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20s%20%3D%20%22bag%22%0A%20%20%20%20t%20%3D%20%22pack%22%0A%20%20%20%20n%2C%20m%20%3D%20len%28s%29%2C%20len%28t%29%0A%0A%20%20%20%20%23%20%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%0A%20%20%20%20res%20%3D%20edit_distance_dp%28s%2C%20t%29%0A%20%20%20%20print%28f%22%D0%A7%D1%82%D0%BE%D0%B1%D1%8B%20%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%7Bs%7D%20%D0%B2%20%7Bt%7D%2C%20%D0%BD%D1%83%D0%B6%D0%BD%D0%BE%20%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D1%83%D0%BC%20%7Bres%7D%20%D1%88%D0%B0%D0%B3%D0%BE%D0%B2%22%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=6&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Во весь экран ></a></div></p>
|
||||
</details>
|
||||
<p>Как показано на рисунке 14-30, процесс переходов состояния в задаче о расстоянии редактирования очень похож на процесс в задачах о рюкзаке: в обоих случаях это заполнение двумерной сетки.</p>
|
||||
<p>Как показано на рисунке 14-30, процесс переходов состояния в задаче о расстоянии редактирования очень похож на задачи о рюкзаке: и там и здесь его можно рассматривать как заполнение двумерной сетки.</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="2:15"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><input id="__tabbed_2_12" name="__tabbed_2" type="radio" /><input id="__tabbed_2_13" name="__tabbed_2" type="radio" /><input id="__tabbed_2_14" name="__tabbed_2" type="radio" /><input id="__tabbed_2_15" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1"><1></label><label for="__tabbed_2_2"><2></label><label for="__tabbed_2_3"><3></label><label for="__tabbed_2_4"><4></label><label for="__tabbed_2_5"><5></label><label for="__tabbed_2_6"><6></label><label for="__tabbed_2_7"><7></label><label for="__tabbed_2_8"><8></label><label for="__tabbed_2_9"><9></label><label for="__tabbed_2_10"><10></label><label for="__tabbed_2_11"><11></label><label for="__tabbed_2_12"><12></label><label for="__tabbed_2_13"><13></label><label for="__tabbed_2_14"><14></label><label for="__tabbed_2_15"><15></label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -4863,7 +4863,7 @@ dp[i, j] = dp[i-1, j-1]
|
||||
|
||||
<h3 id="3">3. Оптимизация пространства<a class="headerlink" href="#3" title="Permanent link">¶</a></h3>
|
||||
<p>Поскольку <span class="arithmatex">\(dp[i,j]\)</span> зависит от значения сверху <span class="arithmatex">\(dp[i-1, j]\)</span> , слева <span class="arithmatex">\(dp[i, j-1]\)</span> и слева сверху <span class="arithmatex">\(dp[i-1, j-1]\)</span> , прямой обход после оптимизации памяти теряет значение слева сверху, а обратный обход не позволяет заранее построить значение слева <span class="arithmatex">\(dp[i, j-1]\)</span> . Значит, оба наивных варианта обхода здесь непригодны.</p>
|
||||
<p>Чтобы решить эту проблему, можно использовать переменную <code>leftup</code> для временного сохранения значения слева сверху <span class="arithmatex">\(dp[i-1, j-1]\)</span> ; после этого остается учитывать только верхнее и левое значения. Тогда ситуация становится эквивалентной задаче о полном рюкзаке, и можно выполнять прямой обход. Код приведен ниже:</p>
|
||||
<p>Чтобы решить эту проблему, можно использовать переменную <code>leftup</code> для временного сохранения значения слева сверху <span class="arithmatex">\(dp[i-1, j-1]\)</span> ; после этого остается учитывать только верхнее и левое значения. Тогда ситуация становится аналогичной задаче о полном рюкзаке, и можно выполнять прямой обход. Код приведен ниже:</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="3:13"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><input id="__tabbed_3_13" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Python</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Java</label><label for="__tabbed_3_4">C#</label><label for="__tabbed_3_5">Go</label><label for="__tabbed_3_6">Swift</label><label for="__tabbed_3_7">JS</label><label for="__tabbed_3_8">TS</label><label for="__tabbed_3_9">Dart</label><label for="__tabbed_3_10">Rust</label><label for="__tabbed_3_11">C</label><label for="__tabbed_3_12">Kotlin</label><label for="__tabbed_3_13">Ruby</label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
@@ -5298,7 +5298,7 @@ aria-label="Нижний колонтитул"
|
||||
<a
|
||||
href="../unbounded_knapsack_problem/"
|
||||
class="md-footer__link md-footer__link--prev"
|
||||
aria-label="Назад: 14.5 Задача о неограниченном рюкзаке"
|
||||
aria-label="Назад: 14.5 Задача о полном рюкзаке"
|
||||
rel="prev"
|
||||
>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -5310,7 +5310,7 @@ aria-label="Нижний колонтитул"
|
||||
Назад
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user