Проблема в следующем:
Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6 routes to the bottom right corner. How many such routes are there through a 20×20 grid?
Мой код здесь:
public static void main(String[] args){
BigInteger twenty = factorial(new BigInteger("20"));
System.out.println(choose(twenty.add(twenty),twenty));
}
public static BigInteger choose(BigInteger n, BigInteger k){
return factorial(n).divide(factorial(n.subtract(k)).multiply(factorial(k)));
}
public static BigInteger factorial(BigInteger n){
BigInteger num = BigInteger.ONE;
if (n.equals(BigInteger.ZERO)){
return BigInteger.ONE;
}
else{
BigInteger i = BigInteger.ONE;
while (i.compareTo(new BigInteger(n+"")) <= 0){
num = num.multiply(new BigInteger(i+""));
i = i.add(BigInteger.ONE);
}
}
return num;
}
Это работает для приведенного примера, но, конечно, требуется очень много времени, чтобы вычислить ответ для сетки 20x20. Я понимаю, что возможные пути равны a + b, выберите a. Единственная проблема в том, что мой код занимает много времени. Есть ли способ повысить эффективность моей программы?
Ваши входы n и k просто должны быть int, а не BigInteger. Конечно, результат может потребоваться BigInteger, но входы, скорее всего, этого не делают.
Тукучи, как можно отказаться от подобных вещей? Есть ли хорошие ресурсы по этой теме?




Вы рекурсивно вычисляете факториал, а затем делите факториалы. Попытайтесь проработать это на бумаге и посмотреть, не отменяется ли что-то, а затем подумайте, как можно избежать вычисления всей этой самоподавляющейся части. Также подумайте о ведении таблицы промежуточных факториалов, чтобы не пересчитывать их.