![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
По внутренней рассылке прислали задачку. Очень может быть, что нетривиальную; решения я не знаю. Звучит красиво... думаю.
Пусть у нас есть какой-то набор достоинств монет, так, что любую сумму можно собрать из монет данного набора (количество индивидуальных монет каждого достоинства неограничено). Для любой суммы, чтобы собрать ее посредством данного набора, можно воспользоваться "жадным" алгоритмом: каждый раз брать наибольшую возможную монету, меньшую оставшейся суммы, вычитать ее, и продолжать так, пока ничего не останется.
Есть наборы, для которых "жадный" алгоритм всегда приведет к наименьшему возможному количеству монет (скажем, набор из 10, 5, 3 и 1 - такой). А есть наборы, для которых иногда можно воспользоваться меньшим количеством монет, чем дает "жадный" алгоритм (например, набор достоинств в 25, 20, 10, 5 и 1 такой: сумму в 40 денежных единиц можно в нем выразить двумя монетами по 20, а "жадный" алгоритм дает три монеты: 25, 10 и 5).
Вопрос: как для любого набора определить, к какой из этих двух групп он относится, т.е. всегда ли жадный алгоритм дает для него наименьшее количество монет?
P.S. Если вы просто знаете правильное решение (а не придумали его сами), не надо им делиться пока, хочу подумать сам.
Пусть у нас есть какой-то набор достоинств монет, так, что любую сумму можно собрать из монет данного набора (количество индивидуальных монет каждого достоинства неограничено). Для любой суммы, чтобы собрать ее посредством данного набора, можно воспользоваться "жадным" алгоритмом: каждый раз брать наибольшую возможную монету, меньшую оставшейся суммы, вычитать ее, и продолжать так, пока ничего не останется.
Есть наборы, для которых "жадный" алгоритм всегда приведет к наименьшему возможному количеству монет (скажем, набор из 10, 5, 3 и 1 - такой). А есть наборы, для которых иногда можно воспользоваться меньшим количеством монет, чем дает "жадный" алгоритм (например, набор достоинств в 25, 20, 10, 5 и 1 такой: сумму в 40 денежных единиц можно в нем выразить двумя монетами по 20, а "жадный" алгоритм дает три монеты: 25, 10 и 5).
Вопрос: как для любого набора определить, к какой из этих двух групп он относится, т.е. всегда ли жадный алгоритм дает для него наименьшее количество монет?
P.S. Если вы просто знаете правильное решение (а не придумали его сами), не надо им делиться пока, хочу подумать сам.
no subject
Date: 2007-07-07 10:45 pm (UTC)no subject
Date: 2007-07-08 12:01 am (UTC)no subject
Date: 2007-07-07 11:08 pm (UTC)no subject
Date: 2007-07-07 11:14 pm (UTC)no subject
Date: 2007-07-08 03:48 pm (UTC)Это, пожалуй, достаточное условие. Но необходимое ли?
no subject
Date: 2007-07-07 11:08 pm (UTC)то есть в наборе есть 1?
или предполагалось "любую сумму свыше определенной можно собрать из монет данного набора" (то есть НОК набора равен 1).
Не уверен, что это влияет на решение, но все же.
no subject
Date: 2007-07-07 11:30 pm (UTC)Вариант "любую сумму свыше определенной" не подходит - это условие можно было бы опустить не меняя существенно задачи.
no subject
Date: 2007-07-07 11:59 pm (UTC)no subject
Date: 2007-07-07 11:23 pm (UTC)no subject
Date: 2007-07-07 11:27 pm (UTC)no subject
Date: 2007-07-08 12:31 am (UTC)Результат, который я в ней знаю - да, вполне приличный.
Но, между прочем, получен он был школьником 10-го класса
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:Дальнейшая история
From:Re: Дальнейшая история
From:Re: Дальнейшая история
From:Re: Дальнейшая история
From:no subject
Date: 2007-07-07 11:35 pm (UTC)http://groups.google.com/group/fido7.ru.math/browse_thread/thread/9d99e936feed0e4b/
К сожалению, сейчас на Google Groups глюки с кодировками, а где еще можно посмотреть в интернете я не знаю.
Но могу выслать этот тред на емайл, если кому-то интересно.
no subject
Date: 2007-07-07 11:43 pm (UTC)(no subject)
From:оценка
Date: 2007-07-08 12:27 am (UTC)Пусть задан конечный набор монет целочисленного достоинства, где L -- максимальное достоинство монеты (то же самое, видимо, проходит и для нецелочисленных наборов). Предположим, что "жадный" алгоритм в общем случае не приводит к минимальному числу монет, и пусть N -- наименьшее число, для которого "жадный" алгоритм даёт не оптимальный ответ. Достаточно установить справедливость оценки N <= L^2, после чего всё сводится к конечному перебору. (Практически перебор становится меньше, если построить некоторый вспомогательный граф, но я этого описывать не буду.)
Далее действуем так. Для представления числа K в виде суммы слагаемых k_1+...+k_s можно нарисовать "арки", то есть взять отрезок длиной K, разбить его на части с длинами k_1,...,k_s, соответственно, а затем соединить точки деления дугами в верхней или нижней полуплоскости. На таком языке далее удобно будет вести описание.
У нас имеется два представления числа N в виде суммы невозрастающих слагаемых, причём первое соответствует "жадному" алгоритму. Нарисуем соответствующие арки сверху отрезка длиной N, а для второго представления с меньшим числом слагаемых нарисуем арки снизу (их длины также не возрастают).
Из условия выбора числа N ясно, что у верхних арок нет общих внутренних точке с нижними. Первая слева арка верхнего разложения строго длиннее первой слева нижней. Кроме того, без ограничения общности можно считать, что все нижние арки кроме первой формируют разложение получающегося при этом числа по "жадному" алгоритму.
Разобьём отрезок длиной N на кусочки, отмечая на нём концы всех используемых арок. Кусочек может а) сопадать с одной из арок (верхней или нижней), б) быть началом верхней арки и концом нижней, в) быть концом верхней арки и началом нижней -- начала и концы здесь полагаются собственными.
Докажем, что кусочки типа б) имеют попарно различные длины. Аналогично для кусочков типа в).
Предположим, что есть два кусочка типа б) длиной u. (Тут удобно сделать рисунок для наглядности.) Тогда имеем N=N1+u+N2+u+N3, где в верхнем разбиении N1, u+N2, u+N3 будут полностью состоять из арок, а в нижнем то же верно относительно N1+u, N2+u, N3.
Рассмотрим число N'=N1+u+N3, представляя его двумя способами в виде слагаемых: N1+(u+N3) для верха, с заведомо "жадным" алгоритмом и (N1+u)+N3 для низа. При этом изъятое как сверху, так и снизу количество арок равно одному и тому же числу -- количеству слагаемых, к которому приводит "жадный" алгоритм, применённый к числу u+N2=N2+u. Мы получим число, N', меньшее N, у которого вверху арок больше чем внизу, и при этом верхнее разбиение соответствует "жадному" алгоритму. Это приводит к противоречию с выбором числа N.
Легко понять, что длина отрезка типа б) или в) не превосходит L/2. (Для более грубой оценки можно было бы взять L-1.) Запишем теперь N в виде суммы N=v_0+u+1+v_1+...+u_r+v_r, где u_1,...,u_r -- все части типа б) или в). Из того, что все части типа б) попарно различны по длине, следует, что их не больше L/2. То же для частей типа в), откуда r <= L.
Положим для удобства u_0=u_{r+1}=0. Из устройства арок ясно, что u_{i}+v_{i}+u+{i+1} есть длина арки при любом i от 0 до r, а потому она не больше L. Тогда получаем, что N=(u_0+v_1+u_1)+...+(u_r+v_r+u_{r+1})-(u_1+...+u_r) <= L(r+1)-r=(L-1)r+L <= (L-1)L+L=L^2.
QED
Re: оценка
Date: 2007-07-08 12:44 am (UTC)Но, наверное, это все же "нечестное" решение в том смысле, что требуется придумать что-то интересное, связанное со свойствами самих чисел, а не алгоритм, который теоретически все проверит путем долгого перебора.
Re: оценка
From:2L вместо L^2
From:совсем простой алгоритм
From:Re: совсем простой алгоритм
From:Re: совсем простой алгоритм
From:циклы
From:Re: циклы
From:деление с остатком
From:Re: циклы
From:всё верно
From:no subject
Date: 2007-07-08 12:47 am (UTC)Вроде бы то, что я знаю, вообще не требует перебора.
Там рассматриваются примерно C_n^2 конкретных чисел, для каждого из которых сравниваются две величины - длина жадного представления и длина еще одного конкретного представления. Если для каждого из этих чисел жадное разложение _не длиннее альтернативного_, то жадный алгоритм будет давать кратчайшее представление для любой суммы.
Обратная теорема тоже верна.
no subject
Date: 2007-07-08 12:53 am (UTC)no subject
Date: 2007-07-08 01:03 am (UTC)Разница номиналов любой пары последующих монет (N1 < N2) меньше чем N2*2 :)
В таких случаях нежадный алгоритм может построить сумму N2*2 взяв две монетки N2. А жадный алгоритм всегда будет использовать N1 + a*N3 + b*N4 .... что будет 3 или более монет.
Осталось понять как написать математическое доказательство. Тупею от года в год :(
no subject
Date: 2007-07-08 01:06 am (UTC)no subject
Date: 2007-07-08 01:09 am (UTC)(no subject)
From:no subject
Date: 2007-07-08 04:07 am (UTC)а вот и теория, ага.
Date: 2007-07-08 04:08 am (UTC)Re: а вот и теория, ага.
From:no subject
Date: 2007-07-08 05:53 am (UTC)Кстати, пославший задачу - автор сайта advogato.org.
no subject
Date: 2007-07-08 05:31 pm (UTC)Нутром чую, доказать не могу, тесты подтверждают.
no subject
Date: 2007-07-08 05:52 pm (UTC)Обещанный ТеХ 1993 года
Date: 2007-07-09 08:40 am (UTC)В архиве - TeX-файл и на всякий случай pdf-ка, сделанная из dvi.
Объем - ок. 260 Кб.
http://www.chgk.info/~knop/articles/p93money.zip
no subject
no subject
Date: 2007-07-12 05:17 pm (UTC)