Описание проблемы:
В положительном целых числах вы можете выполнить любой из следующих трех шагов.
- Вычтите 1 из него. (n = n - 1)
- Если его делится на 2, разделите на 2. (если n% 2 == 0, то n = n/2)
- Если его делится на 3, разделите на 3. (если n% 3 == 0, то n = n/3).
Теперь вопрос заключается в том, что при положительном целом n найдется минимальное количество шагов, принимающих n до 1
например:
- Для n = 1 вывод: 0
- Для n = 4 выход: 2 (4/2 = 2/2 = 1)
- При n = 7 вывод: 3 (7 -1 = 6/3 = 2/2 = 1)
Я знаю решение, использующее динамическое программирование и имеющее целочисленный массив. вот код.
public int bottomup(int n) {
//here i am defining an integer array
//Exception is thrown here, if the n values is high.
public int[] bu = new int[n+1];
bu[0] = 0;
bu[1] = 0;
for(int i=2;i<=n;i++) {
int r = 1+bu[i-1];
if(i%2 == 0) r = Math.min(r,1+bu[i/2]);
if(i%3 == 0) r = Math.min(r,1+bu[i/3]);
bu[i] = r;
}
return bu[n];
}
Но я хочу решить это, используя меньшее пространство. Это решение бросает OutofMemoryError в java, если n = 100000000.I не хочу увеличивать мое пространство кучи. Кто-нибудь имеет решение, используя меньшее пространство?
Обратите внимание, что эта проблема не может быть решена с помощью жадного algorthm.Используется один цикл while и проверяется на делимость на 3 и делится на 2 wont work. Вы должны использовать динамическое программирование .please, если у любого есть решение, использующее меньшее пространство.
например:
При n = 10 жадный алгоритм составляет 10/2 = 5 -1 = 4/2 = 2/2 = 1, который занимает 4 шага. В качестве решения должно быть 10-1 = 9/3 = 3/3 = 1, 3 шага.
Я даже попробовал решение по загрузке.
public int[] td = null;
public int topdown(int n) {
if(n <= 1) return 0;
int r = 1+topdown(n-1);
if(td[n] == 0) {
if(n%2 == 0) r = Math.min(r,1+topdown(n/2));
if(n%3 == 0) r = Math.min(r,1+topdown(n/3));
td[n] = r;
}
return td[n];
}
он не работает при n = 10000.