<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ruslan.tkhakokhov&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ruslan.tkhakokhov&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Ruslan.tkhakokhov"/>
		<updated>2026-05-19T18:48:06Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42758</id>
		<title>Оптимальный префиксный код с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42758"/>
				<updated>2014-12-23T17:42:54Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
==Пример.==&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 1111&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 1110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 10&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 0&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 000&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 001&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 010&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 011&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}\dots2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42757</id>
		<title>Оптимальный префиксный код с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42757"/>
				<updated>2014-12-23T17:40:54Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
==Пример.==&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 1111&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 1110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 10&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 0&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 000&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 001&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 010&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 011&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42756</id>
		<title>Оптимальный префиксный код с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42756"/>
				<updated>2014-12-23T17:39:52Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
==Пример.==&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 1111&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 1110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 10&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 0&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 000&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 001&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 010&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 011&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42755</id>
		<title>Оптимальный префиксный код с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42755"/>
				<updated>2014-12-23T17:38:15Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
==Пример.==&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 1111&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 1110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 10&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 0&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 000&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 001&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 010&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 011&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42754</id>
		<title>Оптимальный префиксный код с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42754"/>
				<updated>2014-12-23T17:34:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
==Пример.==&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42574</id>
		<title>Оптимальный префиксный код с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42574"/>
				<updated>2014-12-18T17:03:31Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: Новая страница: «'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в которо...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42573</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42573"/>
				<updated>2014-12-18T17:02:33Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42572</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42572"/>
				<updated>2014-12-18T16:58:32Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42571</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42571"/>
				<updated>2014-12-18T16:57:56Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || &amp;lt;tex&amp;gt; (2^{-1}; 1),  (2^{-2}; 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &amp;lt;tex&amp;gt;(2^{-1}; 2), (2^{-2}; 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &amp;lt;tex&amp;gt; (2^{-1}; 3), (2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42570</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42570"/>
				<updated>2014-12-18T16:57:12Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || (2^{-1}; 1),  (2^{-2}; 1)&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || (2^{-1}; 2), (2^{-2}; 2)&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 ||  (2^{-1}; 3), (2^{-2}; 3)&lt;br /&gt;
|}&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42569</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42569"/>
				<updated>2014-12-18T16:55:46Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|-&lt;br /&gt;
| A || 1 ||  &lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || &lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 3 || &lt;br /&gt;
|}&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42568</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42568"/>
				<updated>2014-12-18T16:53:35Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|-&lt;br /&gt;
| A || 1 ||  &lt;br /&gt;
|-&lt;br /&gt;
| B || 2 || &lt;br /&gt;
|-&lt;br /&gt;
| C || 3 || &lt;br /&gt;
|}&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42567</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42567"/>
				<updated>2014-12-18T16:49:58Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42566</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42566"/>
				<updated>2014-12-18T16:45:52Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42565</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42565"/>
				<updated>2014-12-18T16:44:51Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42564</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42564"/>
				<updated>2014-12-18T16:44:24Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задача о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42563</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42563"/>
				<updated>2014-12-18T16:42:56Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Задача_о_рюкзаке | Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42562</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42562"/>
				<updated>2014-12-18T16:41:19Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42561</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42561"/>
				<updated>2014-12-18T16:38:02Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42560</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42560"/>
				<updated>2014-12-18T16:35:00Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42559</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42559"/>
				<updated>2014-12-18T16:31:53Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42558</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42558"/>
				<updated>2014-12-18T16:29:51Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит'''  — это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42556</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42556"/>
				<updated>2014-12-18T14:00:44Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42555</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42555"/>
				<updated>2014-12-18T13:59:43Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к задаче о рюкзаке.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;ex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-1}; 2), (2^{-1}; 3), (2^{-2}; 1), (2^{-2}; 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42554</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42554"/>
				<updated>2014-12-18T13:51:30Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''. &lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину L бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42553</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42553"/>
				<updated>2014-12-18T13:43:38Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''. &lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Заметим, что самое длинное кодовое слово имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При этом очевидно, что если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;, то перефиксного кода с длиной слова не более &amp;lt;tex&amp;gt; L &amp;lt;/tex&amp;gt; бит не существует.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42526</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42526"/>
				<updated>2014-12-18T05:26:37Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''. &lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Заметим, что самое длинное кодовое слово имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При этом очевидно, что если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;, то перефиксного кода с длиной слова не более &amp;lt;tex&amp;gt; L &amp;lt;/tex&amp;gt; бит не существует.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42525</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42525"/>
				<updated>2014-12-18T05:23:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''. &lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Заметим, что самое длинное кодовое слово имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При этом очевидно, что если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;, то перекидного кода с длиной слова не более &amp;lt;tex&amp;gt; L &amp;lt;/tex&amp;gt; бит не существует.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42524</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42524"/>
				<updated>2014-12-18T05:22:14Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''. &lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Заметим, что самое длинное кодовое слово имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42501</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42501"/>
				<updated>2014-12-17T17:27:18Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''. &lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Заметим, что самое длинное кодовое слово имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42499</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42499"/>
				<updated>2014-12-17T17:26:45Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''. &lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 1111 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 1110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 110 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Заметим, что самое длинное кодовое слово имеет длину 4. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 000 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 001 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 010 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; D = 011 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; E = 100 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42489</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42489"/>
				<updated>2014-12-17T16:44:47Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42488</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42488"/>
				<updated>2014-12-17T16:40:20Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42486</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42486"/>
				<updated>2014-12-17T16:37:11Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{0} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 00 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42485</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42485"/>
				<updated>2014-12-17T16:36:18Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 00 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42484</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42484"/>
				<updated>2014-12-17T16:35:30Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || X || X || X &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || X || X&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 00 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42482</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42482"/>
				<updated>2014-12-17T16:34:41Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 00 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42481</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42481"/>
				<updated>2014-12-17T16:33:51Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 00 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding — Huffman Coding]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm - Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code - Canonical Huffman code]&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42480</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42480"/>
				<updated>2014-12-17T16:29:01Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 00 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42479</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42479"/>
				<updated>2014-12-17T16:28:28Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 00 &amp;lt;/tex&amp;gt;&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42478</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42478"/>
				<updated>2014-12-17T16:24:29Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{1, 2, 3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; - соответсвующие длины кодовых слов&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42477</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42477"/>
				<updated>2014-12-17T16:21:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{1,2,2\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42476</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42476"/>
				<updated>2014-12-17T16:20:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка. Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;. Обратите внимание, что при подсчете количества монет определенного веса мы учитываем монеты, которые были даны изначально, а не те, которые получились путем слияния исходных.&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{1,2,2\}&amp;lt;/tex&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42474</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42474"/>
				<updated>2014-12-17T16:18:03Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Теперь нам нужно набрать монеты суммарным номиналом &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом, т.е. просто возьмем первые две монеты из итогового списка.&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42472</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42472"/>
				<updated>2014-12-17T16:16:27Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение второго списка по парам:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{0}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{0}; 6)&amp;lt;/tex&amp;gt; || ||&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42471</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42471"/>
				<updated>2014-12-17T16:14:53Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Объединим первый список со вторым:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42470</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42470"/>
				<updated>2014-12-17T16:13:15Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42467</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42467"/>
				<updated>2014-12-17T16:12:00Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список, в котором содержатся монеты номинала 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Выполним объединение первого списка по парам и исключим последний элемент, т.к. для него нет пары:&lt;br /&gt;
&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 3)&amp;lt;/tex&amp;gt; || || &lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42466</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42466"/>
				<updated>2014-12-17T16:08:46Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список. В нем будут содержаться монеты номиналом 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-2}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; ||  &amp;lt;tex&amp;gt;(2^{-1}; 1)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}; 2)&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-2}; 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42465</id>
		<title>Код Хаффмана с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BE%D0%B4_%D0%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=42465"/>
				<updated>2014-12-17T16:07:07Z</updated>
		
		<summary type="html">&lt;p&gt;Ruslan.tkhakokhov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Код Хаффмана с длиной слова не более L бит''' - это вариация классического кода Хоффмана с дополнительным ограничением: длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита, c помощью сведения задачи к одной из вариаций '''задачи о банкомате'''.&lt;br /&gt;
&lt;br /&gt;
== Задача о банкомате. ==&lt;br /&gt;
В вариации задаче о банкомате, которую мы рассмотрим, у вас имеется &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; монет. Каждая монета характеризуется двумя параметрами: номиналом и весом. При этом все номиналы являются степенями двойки и не превышают &amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;. Необходимо выбрать из имеющихся монет некоторый набор так, чтобы их суммарный номинал был равен &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (натуральное число), а суммарный вес минимален.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм решения задачи о банкомате. ==&lt;br /&gt;
Рассмотрим алгоритм решения приведенной выше вариации задачи о банкомате, считая, что решение существует.&lt;br /&gt;
# Разделим имеющиеся у нас монеты на списки по номиналу (свой список для каждого номинала) и упорядочим монеты по возрастанию весов внутри списков, а списки в порядке возрастания номиналов.&lt;br /&gt;
# Рассмотрим первый список (с монетами самого низкого номинала). Разобьем в нем все монеты на пары (1 и 2, 3 и 4 и т. д.) Заменим каждую пару монет одной новой монетой, номинал и вес которой равен сумме номиналов и весов старых. Если число монет было нечетно, то последнюю монету, которая не имеет пары, исключим из рассмотрения.&lt;br /&gt;
# Объединим первый список со вторым так, чтобы монеты в получившемся списке остались упорядочены по весу.&lt;br /&gt;
# Будем повторять шаги 2-3 до тех пор, пока у нас не останется один список. В нем будут содержаться монеты номиналом 1 (&amp;lt;tex&amp;gt;2^0&amp;lt;/tex&amp;gt;), упорядоченные по весу. Возьмем первые &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; монет из списка. Это и будет ответ к задаче.&lt;br /&gt;
&lt;br /&gt;
== Сведение к генерации кода Хоффмана с длиной кодового слова не более L бит. ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; - частоты символов алфавита.&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; монет номиналами &amp;lt;tex&amp;gt;2^{-1}..2^{-L}, каждая из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью описанного выше алгоритма выберем набор монет суммарным номиналом &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - количество монет номинала &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; - это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин - в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации кода Хоффмана с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{a_{1},a_{2},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; - ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор монет;&lt;br /&gt;
 &amp;lt;tex&amp;gt;(2^{-1}; 1), (2^{-2}; 1), (2^{-1}; 2), (2^{-2}; 2), (2^{-1}; 3), (2^{-2}; 3)  &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распределим их по спискам:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-2} &amp;lt;/tex&amp;gt; || 1 || 2 || 3&lt;br /&gt;
|-&lt;br /&gt;
| Номинал = &amp;lt;tex&amp;gt; 2^{-1} &amp;lt;/tex&amp;gt; || 1 || 2 || 3&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Ruslan.tkhakokhov</name></author>	</entry>

	</feed>