Пусть n
будет суммой денежных единиц, возвращаемых в качестве сдачи. Вы хотите найти N(n)
количество возможных способов вернуть сдачу.
Одним из простых решений было бы сначала выбрать «первую» монету, которую вы даете (скажем, она имеет значение c
), а затем заметить, что N(n)
— это сумма всех значений N(n-c)
для всех возможных c
. Поскольку это кажется рекурсивной проблемой, нам нужны некоторые базовые случаи. Как правило, у нас будет N(1) = 1
(одна монета достоинством один).
Давайте рассмотрим пример: 3 можно вернуть как «1 плюс 1 плюс 1» или как «2 плюс 1» (при условии, что существуют монеты номиналом один и два). Поэтому N(3)=2
.
Однако, если мы применим предыдущий алгоритм, он вычислит N(3)
равным 3.
+------------+-------------+------------+
| First coin | Second coin | Third coin |
+------------+-------------+------------+
| 2 | 1 | |
+------------+-------------+------------+
| | 2 | |
| 1 +-------------+------------+
| | 1 | 1 |
+------------+-------------+------------+
Действительно, обратите внимание, что возвращение 3 единиц как «2 плюс 1» или как «1 плюс 2» считается нашим алгоритмом двумя разными решениями, хотя они одинаковы.
Поэтому нам необходимо применить дополнительное ограничение, чтобы избежать таких дубликатов. Одно из возможных решений — упорядочить монеты (например, по уменьшению стоимости). Затем накладываем следующее ограничение: если на данном шаге мы вернули монету достоинством c0
, то на следующем шаге мы можем вернуть только монеты достоинством c0
или меньше.
Это приводит к следующему соотношению индукции (учитывая c0
стоимость монеты, возвращенной на последнем шаге): N(n)
представляет собой сумму всех значений N(n-c)
для всех возможных значений c
, меньших или равных c0
.
Удачного кодирования :)
person
Aimery
schedule
10.07.2019