Я наткнулся на эту проблему:Количество способов сделать изменения для количества N
http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
Учитывая значение N, если мы хотим внести изменения в N центов, и у нас есть бесконечный запас каждая из S = {S1, S2, .., Sm} ценных монет, сколько способов мы можем внести изменения? Порядок монет не имеет значения.
Например, для N = 4 и S = {1,2,3} существует четыре решения: {1,1,1,1}, {1,1,2}, {2,2} , {1,3}. Таким образом, выход должен быть 4. Для N = 10 и S = {2, 5, 3, 6} существует пять решений: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} и {5,5}. Таким образом, выход должен быть 5.
Я придумал решение:
// recurrence relation
count[N] = count[N-d] for all denomination <= N
Source code
-----------
public static int numWays(int N, int[] denoms) {
if (N == 0)
return 0;
int[] ways = new int[N+1];
ways[0] = 1;
for (int i=1; i<=N; i++) {
ways[i] = 0;
for (int d : denoms) {
if (d <= i) {
ways[i] += ways[i-d];
}
}
}
return ways[N];
}
Но это считается дубликатами, которые имеют те же номиналы, но в другом порядке. Например, если деноминации = {1,2} и N = 3, то он подсчитывает {1,1,1}, {2,1}, {1,2}, который имеет двойную запись {1,2}.
Я вижу, что решение DP, описанное в ссылке here, позволяет избежать дублирования. Я понимаю, как работает рекуррентное отношение и все, но я не могу понять, как он может избежать дубликатов, пока мое решение не является. Пожалуйста, объясните идею.