https://www.geeksforgeeks.org/program-to-calculate-the-value-of-ncr-efficiently/
это код, который я хочу понять. Вот видео, которое объясняет это более подробно https://thewikihow.com/video_lhXwT7Zm3EU -> однако я до сих пор не понимаю определенного аспекта этого. Вот код:
// Java implementation to find nCr
class GFG {
// Function to find the nCr
static void printNcR(int n, int r)
{
// p holds the value of n*(n-1)*(n-2)...,
// k holds the value of r*(r-1)...
long p = 1, k = 1;
// C(n, r) == C(n, n-r),
// choosing the smaller value
if (n - r < r) {
r = n - r;
}
if (r != 0) {
while (r > 0) {
p *= n;
k *= r;
// gcd of p, k
long m = __gcd(p, k);
// dividing by gcd, to simplify
// product division by their gcd
// saves from the overflow
p /= m;
k /= m;
n--;
r--;
}
// k should be simplified to 1
// as C(n, r) is a natural number
// (denominator should be 1 ) .
}
else {
p = 1;
}
// if our approach is correct p = ans and k =1
System.out.println(p);
}
static long __gcd(long n1, long n2)
{
long gcd = 1;
for (int i = 1; i <= n1 && i <= n2; ++i) {
// Checks if i is factor of both integers
if (n1 % i == 0 && n2 % i == 0) {
gcd = i;
}
}
return gcd;
}
// Driver code
public static void main(String[] args)
{
int n = 50, r = 25;
printNcR(n, r);
}
}
В частности, почему этот код работает:
if (n - r < r)
r = n - r;
Почему, выполняя эту простую операцию, в конечном итоге выдает правильный ответ после прохождения и выхода из основного цикла while? Я не понимаю, зачем это нужно и почему это имеет смысл делать. Например, почему без этого кода расчет nCr не работает или не работает так, как задумано???? Если кто-то может объяснить это или указать мне где-нибудь, где это объясняется, или математическая концепция, или что-то еще, это было бы здорово :) Может быть, помог бы другой способ кодирования того же самого. Я просто хочу понять, почему это дает правильный ответ для студента, изучающего математику и программирование. Чтобы дать некоторое представление о моих способностях (чтобы вы знали, на каком я уровне), я изучаю объектно-ориентированное программирование и закончил среднюю школу по математике и основам информатики. Я ни в коем случае не эксперт.
У операции nCr
есть особенность, и она упоминается в комментарии над условием if
: // C(n, r) == C(n, n-r)
. Теперь цикл while повторяется, когда r>0
, и с каждой итерацией значение r уменьшается на 1
. Таким образом, чтобы уменьшить количество выполнений цикла, нам нужно уменьшить значение r (если возможно). Поскольку C(n, r) == C(n, n-r)
, мы берем меньшее значение из r
и n-r
, чтобы количество итераций было минимальным, но результат оставался прежним.
Предположим, что n = 100
и r=99
. В этом случае, если мы пропустим условие if
, то цикл будет выполнен 99
раз, тогда как с помощью условия if
мы можем обновить r
как r = n-r
, чтобы r=1
, тогда цикл был бы выполнен только один раз. Таким образом мы спасаем 98
нежелательные итерации.
Таким образом, если мы включим условие if
, производительность значительно улучшится.
По сравнению с чем? Конечно, более важным вопросом является... почему какой-то другой метод расчета дает неверные результаты.