Рекурсия по обмену монет Все решения на разные решения
Я новичок в рекурсии и возврата. Я знаю, что должен полностью освоиться с этими концепциями, прежде чем перейти к динамическому программированию. Ниже я написал программу, которая помогает мне найти все возможные комбинации для заданного количества n и неограниченного количества монет. Однако я хочу, чтобы моя программа дала мне отличные решения. Мне трудно понять, как это сделать.
Я нашел ресурс здесь: Изменение монеты, которое рекурсивно использует нисходящий подход, а затем модифицирует его, чтобы дать различные комбинации, используя следующую формулу: count (s, n, total) = count (s, n, total-s[n]) + количество (с, n-1, всего)
Это говорит о том, что я рекурсивно использую значение, а затем рекурсивно, исключая значение и уменьшая монеты на 1.
Я не могу понять, как это работает. Также я могу с уверенностью сказать, что было бы довольно сложно даже подумать о такой технике на месте во время интервью. Кажется, что кому-то в какой-то момент пришлось бы потратить значительное количество времени на такую проблему, чтобы разработать такую технику.
В любом случае, любая помощь по поводу того, как я могу преобразовать свою программу для печати отдельных решений и как она работает, будет очень полезна.
public class Recursive {
static int[] combo = new int[100];
public static void main(String argv[]) {
int n = 8;
int[] amounts = {1, 5, 10};
ways(n, amounts, combo, 0, 0, 0);
}
public static void ways(int n, int[] amounts, int[] combo, int count, int sum, int index) {
if(sum == n) {
printArray(combo, index);
}
if(sum > n) {
return;
}
for(int i=0;i<amounts.length;i++) {
sum = sum + amounts[i];
combo[index] = amounts[i];
ways(n, amounts, combo, 0, sum, index + 1);
sum = sum - amounts[i];
}
}
public static void printArray(int[] combo, int index) {
for(int i=0;i < index; i++) {
System.out.print(combo[i] + " ");
}
System.out.println();
}
}
Фактическое количество неделимых действительных комбинаций для сумм {1, 2, 5} и N = 10 составляет 128 с использованием чисто рекурсивного исчерпывающего метода (код ниже).
Мой вопрос заключается в том, можно ли улучшить поиск с помощью запоминания / динамического программирования. Если так, как я могу изменить алгоритм ниже, чтобы включить такие методы.
1 ответ
Простые модификации позволяют избежать повторов.
Использовать отсортировано amounts
массив.
Начальное значение цикла должно исключать предыдущие значения из amounts
,
я использовал count
аргумент (кажется, не используется)
for(int i=count;i<amounts.length;i++) {
sum = sum + amounts[i];
combo[index] = amounts[i];
ways(n, amounts, combo, i, sum, index + 1);
sum = sum - amounts[i];
}
static HashMap<Integer, Integer> memo = new HashMap<Integer, Integer>();
public static void main(String argv[]) {
int n = 1000;
System.out.println(getSteps(n, 0,0 ));
}
public static int getSteps(int n, int sum, int count) {
if(n == sum) {
return 1;
}
if(sum > n) {
return 0;
}
if(memo.containsKey(sum)) {
return memo.get(sum);
}
for(int i=1; i<=3;i++) {
sum = sum + i;
count += getSteps(n, sum, 0);
sum = sum - i;
memo.put(sum, count);
}
return count;
}