РЕДАКТИРОВАТЬ: N это количество человек. k - это k-й человек, которого исключают. Таким образом, при k = 2 каждый второй человек устраняется.
int josephus(int n, int k)
{
if (n == 1)
return 1;
else
return (josephus(n - 1, k) + k-1) % n + 1;
}
Код настолько прост, насколько это возможно. Но почему-то я не могу понять эту проблему (что немного смущает, если честно).
То, как я пытаюсь понять это,
- josephus (n, k) дает окончательное решение для населения размера n и размера шага k.
- josephus (n, k) можно вычислить, если мы знаем решение для josephus (n-1, k). Это, на мой взгляд, "оптимальное свойство субструктуры" динамического программирования.
- Я понял, что нам нужно сделать MOD N, чтобы в случае, если число прошло n, он снова начнет считать с 1. (т.е. убедитесь, что сложение ведет себя так, как мы считаем по кругу). Но почему мы добавили этот "к-1"?
Главный вопрос: если мы знаем правильное решение Иосифа (n-1, k), как мы вычисляем решение для Иосифа (n, k). Мы фактически добавили еще одного человека к населению, и каким-то образом добавив это значение k-1, я получаю правильное решение (пусть на мгновение проигнорирует мод).
Может ли кто-нибудь объяснить мне, как оптимальное свойство субструктуры удерживается на каждом этапе проблемы?