Некоторое заранее неизвестное количество людей хотят сброситься и купить некий товар. Требуется: придумать схему сбора денег, при которй минимизируется (а) время до покупки, (б) дальнейшая беготня и разборки, кто кому чего должен.
Если бы N было заранее известно, все бы скинулись по 1/N и всё. Для минимизации (а) немного видоизменяем — 1-й сразу покупает вещь, а потом остальные N-1 отдают ему по 1/N.
Но фишка в том, что N заранее неизвестно, а может быть, и не ограничено. Но желающие скидываться могут кончиться в любой момент.
Пример плохого решения:
1-й покупает вещь.
2-й отдаёт ему половину стоимости.
3-й отдаёт 1-му и 2-му по 1/6.
4-й отдаёт 1-му, 2-му и 3-му по 1/12.
…
N-й отдаёт (1..N-1)-му по 1/(N*(N-1)).
Преимущество: после каждой итерации распределение вкладов «справедливое».
Недостаток: требует sum(i-1, i=1..N) ~ O(N^2) передач.
[edit]
Если не требовать, чтобы скидывались строго по одинаковой сумме, то можно придумать схему с N-1 передачей, для которой отклонение от «справедливого» распределения будет вести себя вот так: