Binomial əmsalı Seçim n elementdən k elementin seçilməsidir, burada verilmiş n elementdən k elementi seçilir. Bu halda, elementlərin sıralanması fərqli olan dəstlər (lakin tərkibi fərqli olmayan) eyni hesab olunur. Seçimlərin bu xüsusiyyətinə görə onlar yerləşdirmələrdən fərqlənirlər.
Məsələn, 5 elementdən ibarət olan çoxluğu nəzərdən keçirək: \{1, 2, 3, 4, 5\} . \{2, 1, 3\} və \{3, 2, 1\} dəstləri seçim olaraq eyni hesab olunur (yerdəyişmə olaraq fərqli olsalar da), çünki eyni elementlərdən \{1, 2, 3\} ibarətdir.
n -dən k -yə qədər seçimlərin sayının hesablanması üçün formula belədir
C_n^{k} = {n! \over k! \cdot (n - k)!}
C_n^{k} ədədləri binomial əmsallar adlanır.
n elementdən ibarət olan çoxluqdan sıfır element seçdiyimiz zaman əslində "boş" seçim edirik. Bu kontekstdə boş çoxluq düzgün seçim hesab olunur. Təsəvvür edin ki, n topları olan bir qutunuz var və onlardan 0 ədədini seçmək istəyirsiniz. Heç bir şey seçməsəniz belə, bu yenə də düzgün seçim variantıdır. Beləliklə, C_n^{0} n -dən 0 element seçmənin sayını bildirir ki, bu da 1 -ə bərabərdir.
Bunu heç bir element seçməmək üçün yalnız bir yol kimi nəzərə ala bilərik ki, bu da nəticədə 1 verir.
C_n^{0} = {n! \over 0! \cdot (n - 0)!} = {n! \over 1! \cdot n!} = 1
n elementdən ibarət olan çoxluqdan bir element seçdiyimiz zaman n seçmə variantımız var: n elementdən istənilən birini seçə bilərik. Məsələn, 1 -dən 5 -ə qədər ədədlərdən ibarət olan çoxluqdan ( \{1, 2, 3, 4, 5\} ) bir ədəd seçsək, bu çoxluqdan bir ədəd seçmək üçün 5 variantımız var.
C_n^{1} -in dəyəri n -ə bərabərdir, çünki n elementdən ibarət olan çoxluqdan bir elementi seçmənin n yolu var.
C_n^{1} = {n! \over 1! \cdot (n - 1)!} = n
n elementdən ibarət olan çoxluqdan 2 element seçdiyimiz zaman cütlüklər təşkil edirik. Belə bir cütlüyün qurulması üçün əvvəlcə bir elementi, sonra isə ikinci elementi seçirik.
Beləliklə, n elementdən ibarət olan çoxluqdan cüt elementlərin seçilmə üsullarının ümumi sayı birinci və ikinci elementləri seçmənin yollarının hasilinə bərabərdir: n \cdot (n – 1) .
Lakin, hər bir cütlük iki dəfə sayılır, çünki cütlükdə elementlərin sırası əhəmiyyət daşımır. Məsələn, ( p , q ) və ( q , p ) eyni cütlük hesab olunur. Bunu nəzərə alaraq, cütlüklərin ümumi sayını 2 -yə bölmək lazımdır. Beləliklə, C_n^{2} n \cdot (n – 1) / 2 -yə bərabərdir.
C_n^{2} = {n! \over 2! \cdot (n - 2)!} = {n \cdot (n - 1) \over 2}
Aşağıdakı binomial əmsalların qiymətlərini hesablayın:
C_4^{2} = {4! \over 2! \cdot 2!} = {3 \cdot 4 \over 2} = 6,
C_6^{3} = {6! \over 3! \cdot 3!} = {4 \cdot 5 \cdot 6 \over 6} = 20,
C_7^{3} = {7! \over 3! \cdot 4!} = {5 \cdot 6 \cdot 7 \over 6} = 35
Simmetriya xüsusiyyəti: C_n^{k} = C_n^{n - k} .
n elementdən k elementi seçmənin sayı n elementdən ( n – k ) elementi seçmənin sayına bərabərdir. Amma n elementdən ( n – k ) elementi seçmənin C_n^{n - k} yolu var. Deməli, C_n^{k} = C_n^{n - k} .
Aşağıdakı binomial əmsalların qiymətlərini hesablayın:
C_5^{4} = C_5^{5 - 4} = C_5^{1} = 5,
C_6^{4} = C_6^{6 - 4} = C_6^{2} = {6 \cdot 5 \over 2} = 15
Tapşırıq. Aşağıdakı binomial əmsalların qiymətlərini hesablayın:
1) C_5^{2}
3) C_5^{4}
5) C_8^{1}
2) C_8^{3}
4) C_7^{5}
6) C_8^{5}
Yığma formulu: C_n^{k} = C_{n-1}^{k-1} + C_{n-1}^{k} .
İspat. Bərabərliyin sağ tərəfindəki dəyəri hesablayın:
C_{n-1}^{k-1} + C_{n-1}^{k} = {(n - 1)! \over (k - 1)! \cdot (n - k)!} + {(n - 1)! \over k! \cdot (n - k - 1)!} =
{(n - 1)! \cdot k + (n - 1)! \cdot (n - k) \over k! \cdot (n - k)!} = {(n - 1)! \cdot (k + n - k)\over k! \cdot (n - k)!} = {n! \over k! \cdot (n - k)!} = C_n^{k}
Riyazi analiz imtahanına hazırlaşarkən, Petyanın qarşısında n müxtəlif yazıqlar var idi. Onlar onun xilas yolu idi, çünki bütün semestr boyunca Petya materialı düzgün öyr
ənməyə cəhd etməmişdi. Yazıqlar o qədər çox idi ki, onlar heç bir cibə yerləşmirdi. Buna görə Petya imtahana öz ilə götürə biləcəyi maksimum yazıq sayını hesablamağa qərar verdi. Və burada bir sual meydana çıxdı: ümumiyyətlə lazımi yazıqların sayını seçmənin neçə yolu var?
Giriş məlumatları. Ümumi yazıq sayı n~(1 \le n \le 12) və Petyanın özü ilə götürə biləcəyi yazıq sayı k~(0 \le k \le n) verilmişdir.
Çıxış məlumatları. n yazıqdan k yazıq seçmənin yollarının sayını çıxarın.
Məsələni aç
Binomial əmsalın hesablanması üçün aşağıdakı nisbətdən istifadə edə bilərsiniz:
C_n^{k} = {n! \over k! \cdot (n - k)!} = {n \cdot (n - 1) \cdot (n - 2) \cdot ... \cdot (n - k + 1) \over 1 \cdot 2 \cdot 3 \cdot ... \cdot k}
1 qiyməti ilə dəyişən r es təyin edin. Sonra r es -i n -ə vurun və nəticəni 1 -ə bölün. Sonra r es -i n –1 -ə vurun və 2 -yə bölün. Çoxaltma və bölmə prosesini k dəfə davam etdirin ( C_n^{k} -nin payı və məxrəci ( n – k )! ilə qısaldıqdan sonra k vurucu ehtiva edir).
Cnk funksiyası binomial əmsalın qiymətini iterativ metodla hesablayır.
int Cnk(int n, int k)
{
int res = 1;
for(int i = 1; i <= k; i++)
res = res * (n - i + 1) / i;
return res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
Cavabı hesablayın və çıxarın.
res = Cnk(n,k);
printf("%d\n",res);Binomial əmsalın rekursiv tətbiqi üçün aşağıdakı nisbətdən istifadə edə bilərsiniz:
C_n^{k} = \begin{cases}
C_{n - 1}^{k - 1} + C_{n - 1}^{k}, n > 0 \\
1, k = n~və~ya~k = 0
\end{cases}
Cnk funksiyası binomial əmsalın qiymətini rekursiv metodla hesablayır.
int Cnk(int n, int k)
{
if (n == k) return 1;
if (k == 0) return 1;
return Cnk(n - 1, k - 1) + Cnk(n - 1, k);
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
Cavabı hesablayın və çıxarın.
res = Cnk(n,k);
printf("%d\n",res);n LKS-lər arasında neçə nəfər kefir alacağını seçmək üçün neçə yol var? Cavabı 9929 -a bərabər olaraq çıxarın.
Giriş məlumatları. n və k~(0 \le k \le n \le 500) tam ədədləri.
Çıxış məlumatları. Cavabı 9929 -a bərabər olaraq çıxarın.
Məsələni aç
Məsələnin cavabı C_n^{k}~mod~9929 -a bərabər olacaq. Bərabərliyin hesablanması zamanı bölmədən qaçmaq üçün C_n^{k} = C_{n - 1}^{k} + C_{n - 1}^{k - 1}, C_n^{0} = 1 nisbətindən istifadə edəcəyik.
k \le n \le 500 olduğuna görə, memorizasiya texnikasından istifadə edəcəyik.
Sabitləri və c nk massivini elan edək, burada cnk[n][k] = C_n^{k}~mod~9929 .
#define MAX 510
#define MOD 9929
int cnk[MAX][MAX];c funksiyası C_n^{k}~mod~9929 binomial əmsalın qiymətini hesablayır.
int c(int n, int k)
{
if (cnk[n][k] > 0) return cnk[n][k];
if (n - k < k) return c(n,n-k);
if (!k) return cnk[n][k] = 1;
return cnk[n][k] = (c(n-1,k) + c(n-1,k-1)) % MOD;
}Proqramın əsas hissəsi. c nk massivini sıfırla yükləyin. Giriş məlumatlarını oxuyun.
memset(cnk,0,sizeof(cnk));
scanf("%d %d",&n,&k);Cavabı hesablayın və çıxarın.
Binomial əmsallar Nyuton binomunda görünür:
(x + y)^n = \sum_{k=0}^n C_n^{k}x^{k}y^{n-k}
Nümunələri nəzərdən keçirək:
(x + y)^2 = C_2^{0}x^{2}y^{0} + C_2^{1}x^{1}y^{1} + C_2^{2}x^{0}y^{2} = x^2 + 2xy + y^2,
(x + y)^3 = C_3^{0}x^{3}y^{0} + C_3^{1}x^{2}y^{1} + C_3^{2}x^{1}y^{2} + C_3^{3}x^{0}y^{3} = x^3 + 3x^2y + 3xy^2 + y^3
Verilmiş qeyri-mənfi tam ədəd n üçün binomial əmsalların cəmini tapın
C_n^{0} + C_n^{1} + ... + C_n^{n}
Giriş məlumatları. Bir qeyri-mənfi tam ədəd n~(n \le 60) .
Çıxış məlumatları. Cəmin qiymətini çıxarın.
Məsələni aç
Nyuton binomu formulu belədir:
(a + b)^n = \sum_{i = 0}^n{C_n^ia^ib^{n-i}}
a = b = 1 qiymətini verərsək, bu əlaqə belə görünür:
(1 + 1)^n = \sum_{i = 0}^n{C_n^i1^i1^{n-i}}
və ya
2^n = \sum_{i = 0}^n{C_n^i} = C_n^0 + C_n^1 + ... + C_n^n
Beləliklə, göstərilən cəm 2^n -ə bərabərdir.
Nümunə
n = 1 üçün: C_1^0 + C_1^1 = 1 + 1 = 2
n = 2 üçün: C_2^0 + C_2^1 + C_2^2 = 1 + 2 + 1 = 4
n = 3 üçün: C_3^0 + C_3^1 + C_3^2 + C_3^3 = 1 + 3 + 3 + 1 = 8
Verilmiş qeyri-mənfi tam ədəd n üçün binomial əmsalların kvadratlarının cəmini tapın
(C_n^{0})^2 + (C_n^{1})^2 + (C_n^{2})^2 + ... + (C_n^{n})^2
Giriş məlumatları. Bir qeyri-mənfi tam ədəd n~(n \le 30) .
Çıxış məlumatları. Cəmin qiymətini çıxarın.
Məsələni aç
2 n obyektlərindən a_1, ..., a_{2n} -i nəzərdən keçirək və 2 n obyektlərindən n obyektini seçmənin sayını tapın.
Çoxluğu iki hissəyə bölək: \{a_1, a_2, ..., a_n, a_{n+1}, ..., a_{2n}\} . 2 n obyektlərindən n obyektini seçmək üçün, sol yarıdan (yəni \{a_1, a_2, ..., a_n \} çoxluğundan) k~(k \le n) obyektini və sağ yarıdan n – k obyektini seçmək lazımdır (yəni \{a_{n+1}, a_{n+2}, ..., a_{2n}\} çoxluğundan). Bu seçimi etmənin yollarının sayı vurma qaydasına görə C_n^k \cdot C_n^{n-k} = (C_n^k)^2 -ə bərabərdir. k 0 -dan n -ə qədər dəyişə bildiyi üçün \sum_{k=0}^n{(C_n^k)^2} 2 n -dən n -ə qədər seçmənin yollarının sayına bərabərdir, yəni C_{2n}^n . Beləliklə
(C_n^0)^2 + (C_n^1)^2 + (C_n^2)^2 + ... + (C_n^n)^2 = C_{2n}^n
Nümunə
n = 3 üçün cavab belədir: (C_3^0)^2 + (C_3^1)^2 + (C_3^2)^2 + (C_3^3)^2 = 1^2 + 3^2 + 3^2 + 1^2 = 20
Eyni zamanda C_6^3 = {6! \over 3! \cdot 3!} = {4 \cdot 5 \cdot 6 \over 6} = 20 .
Cnk funksiyası C_n^k binomial əmsalının qiymətini hesablayır.
long long Cnk(long long n, long long k)
{
long long res = 1;
if (k > n - k) k = n - k;
for (long long i = 1; i <= k; i++)
res = res * (n - i + 1) / i;
return res;
}Proqramın əsas hissəsi. Giriş dəyəri n -i oxuyun.
Cavabı hesablayın və çıxarın.
res = Cnk(2*n, n);
printf("%lld\n", res);Verilmiş k və n dəyərlərinə görə aşağıdakı tənliyin natural həllərinin sayını tapın
x_1 + x_2 + ... + x_k = n
Giriş məlumatları. İki natural ədəd k və n~(k \le n \le 100) .
Çıxış məlumatları. Verilmiş tənlik üçün natural həllərin sayını çıxarın. Məlumdur ki, cavab 10^{18} -i keçmir.
Məsələni aç
n vahidlərindən ibarət olan ardıcıllığı nəzərdən keçirək: 111...11 . İki vahid arasında '+' işarəsini qoymaq olar. Məsələn, 11+111+1 . Bu yazı 2 + 3 + 1 cəmini ifadə edəcək, burada hər bir sətir yandakı vahidlərin sayıdır. '+' işarəsini qoymaq üçün mövqelərin sayı n –1 -ə bərabərdir. Çünki k sətirlərini əldə etmək üçün k –1 '+' işarəsini qoymaq lazımdır.
n –1 mövqeyində k –1 plüs işarəsini qoymaq C_{n-1}^{k-1} yolla mümkündür.
Nümunə
x_1 + x_2 + x_3 = 4 tənliyinin üç təbii tam həlli var:
Məsələn, n = 4 vahidləri k = 3 sətirlərə C_2^3 = 3 yolla bölmək olar:
Cnk funksiyası C_n^k binomial əmsalının qiymətini hesablayır.
long long Cnk(long long k, long long n)
{
long long res = 1;
if (k > n - k) k = n - k;
for (long long i = 1; i <= k; i++)
res = res * (n - i + 1) / i;
return res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
scanf("%lld %lld", &k, &n);C_{n-1}^{k-1} cavabını hesablayın və çıxarın.
res = Cnk(k - 1, n - 1);
printf("%lld\n", res);Verilmiş k və n dəyərlərinə görə aşağıdakı tənliyin qeyri-mənfi tam ədəd həllərinin sayını tapın
x_1 + x_2 + ... + x_k = n
Giriş məlumatları. İki natural ədəd k və n~(k \le n \le 100) .
Çıxış məlumatları. Verilmiş tənlik üçün qeyri-mənfi tam ədəd həllərinin sayını çıxarın. Məlumdur ki, cavab 10^{18} -i keçmir.
Məsələni aç
n + k – 1 mövqelərindən ibarət ardıcıllığı nəzərdən keçirək. n mövqeyində 1 qoyulmalıdır. k –1 mövqeyində '+' işarəsi qoyulmalıdır (yəni k sətir almaq üçün).
Hər hansı bir yerdə ədədlər və '+' işarələri yerləşdirilməsi verilmiş tənliyin həllinə uyğun gələcək. Məsələn, x_1 + x_2 + x_3 = 4 tənliyinin bəzi həlləri aşağıdakılardır ( 4 vahid və 2 plüs):
k –1 plüs işarəsini n + k – 1 mövqeyinə qoymaq C_{n+k-1}^{k-1} yolla mümkündür.
Nümunə
x_1 + x_2 + x_3 = 4 tənliyinin həlləri aşağıdakılardır:
(4, 0, 0) və onun 3 dəyişməsi
(3, 1, 0) və onun 6 dəyişməsi
(2, 2, 0) və onun 3 dəyişməsi
(2, 1, 1) və onun 3 dəyişməsi
Ümumilikdə 3 + 6 + 3 + 3 = 15 həll var.
Cnk funksiyası C_n^k binomial əmsalının qiymətini hesablayır.
long long Cnk(long long k, long long n)
{
long long res = 1;
if (k > n - k) k = n - k;
for (long long i = 1; i <= k; i++)
res = res * (n - i + 1) / i;
return res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
scanf("%lld %lld", &k, &n);C_{n+k-1}^{k-1} cavabını hesablayın və çıxarın.
res = Cnk(k - 1, n + k - 1);
printf("%lld\n", res);n qeyri-mənfi tam ədəd olsun. Göstərək ki,
n! = 1 \cdot 2 \cdot ... \cdot n~(0! = 1),
C_n^{k} = {n! \over k! \cdot (n - k)!} (0 \le k \le n)
Verilmiş n və k üçün C_n^{k} -nin qiymətini hesablayın.
Giriş məlumatları. Birinci sətir testlərin sayını t~(t \le 50) ehtiva edir. Növbəti t sətirin hər biri iki tam ədəd n və k~(0 \le n < 2^{64}, 0 \le C_n^{k} < 2^{64}) ehtiva edir.
Çıxış məlumatları. Hər bir test üçün C_n^{k} dəyərini ehtiva edən t sətir çıxışa verin.
Məsələni aç
Hesablamalar 64 bitlik işarəsiz tam ədədlərdən (unsigned long long) istifadə edilərək aparılacaq. Aydındır ki,
C_n^k = {n! \over k! \cdot (n - k)!} = {n \cdot (n - 1) \cdot (n - 2) \cdot ... \cdot (n - k + 1) \over 1 \cdot 2 \cdot 3 \cdot ... \cdot k} = {n \over 1} \cdot {n - 1 \over 2} \cdot {n - 2 \cdot 3} \cdot ... \cdot {n - k + 1 \over k}
Dəyişən r es -ə 1 qiyməti verin, sonra isə onu i = 1 -dən k -yə qədər bütün n - i + 1 / i -ə vurun. Hər dəfə bölmə tam ədədli olacaq, lakin vurma zamanı yüklənmə baş verə bilər. d = res və i-nin ən böyük ortaq böləni olsun. Onda əməliyyat
res = res * (n – i + 1 ) / i
aşağıdakı kimi yazılsın
res = (res / d) * ((n – i + 1 ) / (i / d))
Bu tətbiqlə vurma zamanı yüklənmə baş verməyəcək (cavab 64 bitlik işarəsiz tam ədəddir). Əvvəlcə (n – i + 1 ) / (i / d) bölməsini, sonra isə r es / d -i əldə edilmiş qismətə vurmağı unutmayın.
C_n^k -nı hesablamaq üçün k iterasiya yerinə yetirmək lazımdır. Lakin C_{2000000000}^{1999999999} -u hesablamaq lazım gələrsə nə etməli? Cavab 2^{64} -ü keçməyəcək, ona görə də belə giriş məlumatları mümkündür. C_n^k = C_n^{n - k} olduğuna görə n – k < k olduqda k = n – k qəbul edilməlidir.
Nümunə
Aşağıdakı nümunəni nəzərdən keçirək:
C_6^3 = {6 \over 1} \cdot {5 \over 2} \cdot {4 \over 3} = 15 \cdot {4 \over 3}
15 * {4 \over 3} vurması qalıb. d = 15 və 3-ün ən böyük ortaq böləni = 3 . Buna görə 15 \cdot {4 \over 3} = (15 / 3) \cdot {4 \over 3 / 3} = 5 \cdot {4 \over 1} = 20 .
gcd funksiyası a və b ədədlərinin ən böyük ortaq bölənini hesablayır.
unsigned long long gcd(unsigned long long a, unsigned long long b)
{
return (!b) ? a : gcd(b,a % b);
}Cnk funksiyası binomial əmsalın qiymətini hesablayır.
unsigned long long Cnk(unsigned long long n, unsigned long long k)
{
unsigned long long CnkRes = 1, t, i;
if (k > n - k) k = n - k;
for(i = 1; i <= k; i++)
{Növbəti iterasiyada nəticə m -i keçərsə (məsələni həll etmək üçün C_n^k = m tənliyini axtarırıq), dayanırıq. Bu funksiyadan çıxmaqla yüklənmədən də qaçırıq.
if (1.0 * Res * (n - i + 1) / i > m) return m + 1;
Res = Res * (n - i + 1) / i;
}
return Res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
scanf("%d",&t);
while(t--)
{
scanf("%llu %llu",&n,&k);
res = Cnk(n,k);
printf("%llu\n",res);
}Verilmiş natural ədəd n . Aşağıdakı cəmin qiymətini tapın
1 \cdot C_n^{0} + 2 \cdot C_n^{1} + 3 \cdot C_n^{2} + ... + (n + 1) \cdot C_n^{n}
Giriş məlumatları. Bir natural ədəd n\:(n \le 30) .
Çıxış məlumatları. Axtarılan cəmin qiymətini çıxarın.
Məsələni aç
Verilmiş cəmi aşağıdakı kimi yazın:
1 \cdot C_n^0 + 2 \cdot C_n^1 + 3 \cdot C_n^2 + ... + (n + 1) \cdot C_n^n =
\left( C_n^0 + C_n^1 + C_n^2 + ... + C_n^n \right) + 1 \cdot C_n^1 + 2 \cdot C_n^2 + ... + n \cdot C_n^n
Qövslərdə olan cəm 2^n -ə bərabərdir. Nyuton binomu formulasında
(a + b)^n = \sum_{i=0}^n{C_n^ia^ib^{n-i}}
a = b = 1 qəbul edildikdə, əlaqə belə görünəcək: (1 + 1)^n = \sum_{i=0}^n{C_n^i1^i1^{n-i}} , və ya
2^n = \sum_{i=0}^nC_n^i = C_n^0 + C_n^1 + ... + C_n^n
Qalan cəmi hesablayın:
1 \cdot C_n^1 + 2 \cdot C_n^2 + ... + n \cdot C_n^n =
1 \cdot {n! \over 1! \cdot (n - 1)!} + 2 \cdot {n! \over 2! \cdot (n - 2)!} + ... + n \cdot {n! \over n! \cdot (n - n)!} =
n \cdot \left( {(n - 1)! \over 0! \cdot (n - 1)!} + {(n - 1)! \over 1! \cdot (n - 2)!} + ... + {(n - 1)! \over (n - 1)! \cdot (n - n)!} \right) =
n \cdot \left( C_{n-1}^0 + C_{n-1}^1 + ... + C_{n-1}^{n-1} \right) = n \cdot 2^{n - 1}
Beləliklə, cavab 2^n + n \cdot 2^{n - 1} = (n + 2) \cdot 2^{n - 1} -ə bərabərdir.
Nümunə
n = 3 üçün cavabı hesablayaq. Düzgün hesablama ilə:
1 \cdot C_3^0 + 2 \cdot C_3^1 + 3 \cdot C_3^2 + 4 \cdot C_3^3 = 1 \cdot 1 + 2 \cdot 3 + 3 \cdot 3 + 4 \cdot 1 = 1 + 6 + 9 + 4 = 20
Formula ilə hesablama zamanı: 5 \cdot 2^2 = 20 .
Giriş dəyəri n -i oxuyun.
Cavabı hesablayın və çıxarın.
res = (1LL << (n - 1)) * (n + 2);
printf("%lld\n", res);Alqoritmin tətbiqi – funksiya
Nəticələri yadda saxlamaq üçün massiv təyin edin: dp[n][k] = C_n^k .
Cnk funksiyası C_n^k binomial əmsalının qiymətini hesablayır.
int Cnk(int n, int k)
{
if (n == k) return 1;
if (k == 0) return 1;
if (dp[n][k] != -1) return dp[n][k];
return dp[n][k] = (Cnk(n - 1, k - 1) + Cnk(n - 1, k)) % 9929;
}Proqramın əsas hissəsi. Giriş dəyəri n -i oxuyun.
scanf("%d", &n);
memset(dp, -1, sizeof(dp));Göstərilən cəmi hesablayın.
res = 0;
for (i = 0; i <= n; i++)
res += (i + 1) * Cnk(n, i);Cavabı çıxarın.
Sizdə bir parça kağız var və onda n \cdot m ölçüsündə düzbucaqlı seçirsiniz. Bu düzbucaqlını, onun üzərində yerləşən xətlər ilə birlikdə, şəbəkə adlandıraq. Şəbəkənin sol alt küncündən başlayaraq, karandaşınızı sağ üst küncə hərəkət etdirirsiniz, xətlər üzərində qalaraq yalnız sağa və ya yuxarı hərəkət edirsiniz. Nəticə solda göstərilmişdir:
Həqiqətən bir şah əsər deyilmi? Proseduru yenidən təkrarlayaraq, sağda göstərilmiş şəkildə nəticə əldə edəcəksiniz. İndi isə sual yaranır: bu üsulla neçə fərqli sənət əsəri yaratmaq olar?
Giriş məlumatları. İki təbii ədəd n və m .
Çıxış məlumatları. Yuxarıda təsvir olunan prosedurdan istifadə edərək yaratmaq mümkün olan müxtəlif sənət əsərlərinin sayını çıxarın. Bu sayın 64 bitlik işarəli tam ədədə uyğun gəldiyini deyə bilərik.
Məsələni aç
Axtarılan yol n + m seqmentindən ibarət bir ziqzaqdır. Onlardan n seqmentləri şaquli, qalanları isə üfüqi olmalıdır. n şaquli seqmentləri n + m -dən seçməyin yollarının sayı C_{n+m}^n -ə bərabərdir.
Nümunə
Birinci nümunə üçün n = 3, m = 4 . Cavab C_7^3 = {7! \over 3! \cdot 4!} = {7 \cdot 6 \cdot 5 \over 1 \cdot 2 \cdot 3} = 35 -ə bərabərdir.
İkinci nümunə üçün n = 1, m = 1 . Cavab C_2^1 = {2! \over 1! \cdot 1!} = 2 -ə bərabərdir.
Cnk funksiyası binomial əmsalın qiymətini hesablayır.
long long Cnk(long long n, long long k)
{
long long res = 1;
if (k > n - k) k = n - k;
for (long long i = 1; i <= k; i++)
res = res * (n - i + 1) / i;
return res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
scanf("%lld %lld", &n, &m);C_{n+m}^n cavabını hesablayın və çıxarın.
res = Cnk(n + m, n);
printf("%lld\n", res);Gunnar kifayət qədər yaşlı və unutqan bir tədqiqatçıdır. Hazırda o, sosial şəbəkələrdə təhlükəsizlik mövzusunda məqalə yazır və bu məqalədə bəzi kombinatorika elementləri də yer alır. O, bəzi hesablamaları yoxlamaq üçün binomial əmsalların hesablanması üçün proqram yazıb.
Binomial əmsal C_n^{k} bu ədəddir
C_n^{k} = {n! \over k! \cdot (n - k)!}
n və k qeyri-mənfi ədədlərdir.
Gunnar proqramından istifadə edərək C_n^{k} -ni hesablayıb və nəticədə m ədədini alıb. Təəssüf ki, unutqan olduğuna görə, o, giriş kimi istifadə etdiyi n və k ədədlərini unudub. Bu iki ədəd uzun hesablamaların nəticəsi idi və onlar masasının üzərində olan çoxsaylı kağızlardan birində yazılmışdı. Kağızlarda axtarmaq əvəzinə, o, alınan cavabdan n və k ədədlərini bərpa etməyə qərar verdi. Ona bütün mümkün qiymətləri tapmaqda kömək edə bilərsinizmi?
Giriş məlumatları. Birinci sətir testlərin sayını, ən çox 100 , ehtiva edir. Hər test bir sətirdə verilir və Gunnarın proqramının nəticəsi olan m~(2 \le m \le 10^{15}) tam ədədini ehtiva edir.
Çıxış məlumatları. Hər test üçün iki sətir çap edin. Birinci sətir m ədədini binomial əms
aldan ifadə etməyin üsullarının sayını ehtiva etməlidir. İkinci sətirdə C_n^{k} = m şərtini ödəyən bütün ( n , k ) cütləri olmalıdır. Cütlər n artan sırası ilə və k artan sırası ilə yerləşdirilməlidir. Cütlərin çap formatı nümunədə göstərilmişdir.
1
(2,1)
4
(6,2) (6,4) (15,1) (15,14)Məsələni aç
C_n^k = m şərti yerinə yetirilərsə, onda C_n^{n - k} = m şərti də yerinə yetirilir. k \le n / 2 həllini tapmaq və ( k , n ) cütü ilə birlikdə (k, n – k) cütünü də çıxarmaq kifayətdir. k = n / 2 olduqda bu iki cüt eyni olur.
p -ni C_{2p}^p > m olan ən kiçik ədəd qəbul edək. Onda 0 \le k < p olduğu aydındır.
k -ni sabitləşdirmək üçün C_{2k}^k \le m və f(n) = C_n^k funksiyasını nəzərdən keçirək. Onda 2k \le n \le m aralığında f ( n ) funksiyası artandır. Deməli, f(n) = m tənliyini ikili axtarışla həll etmək olar.
Beləliklə, k~(0 \le k < p) qiymətlərini nəzərdən keçirmək və hər belə k üçün C_n^k = m tənliyini ikili axtarışla həll etmək lazımdır. Tapılan n dəyəri tam ədəd olmalıdır.
Nümunə
C_n^k = 3003 tənliyini nəzərdən keçirək. C_{12}^6 = 924 , C_{14}^7 = 3432 olduğuna görə, 0 \le k \le 6 nəzərdən keçirmək kifayətdir.
k = 2 olduqda C_n^2 = 3003 tənliyini və ya {n \cdot (n - 1) \over 2} = 3003 , n \cdot (n – 1) = 6006 tənliyini nəzərdən keçirək. 4 \le n \le 3003 aralığında ikili axtarışla tam həll n = 78 tapılır. n \ne 2 \cdot k olduğuna görə iki həll var: C_{78}^2 = C_{78}^{76} = 3003 .
Axtarılan cütləri cütlər vektorunda saxlayaq.
vector<pair<long long,long long> > res;Cnk funksiyası C_n^k binomial əmsalının qiymətini hesablayır.
long long Cnk(long long n, long long k)
{
long long i, Res = 1;
if (k > n - k) k = n - k;
for(i = 1; i <= k; i++)
{Növbəti iterasiyada nəticə m -i keçərsə (məsələni həll etmək üçün C_n^k = m tənliyini axtarırıq), dayanırıq. Bu funksiyadan çıxmaqla yüklənmədən də qaçırıq.
if (1.0 * Res * (n - i + 1) / i > m) return m + 1;
Res = Res * (n - i + 1) / i;
}
return Res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyun.
scanf("%d",&tests);
while (tests--)
{
res.clear();
scanf("%lld",&m);k dəyərini C_{2k}^k ≤ m qədər nəzərdən keçirin.
for(k = 0; Cnk(2*k,k) <= m; k++)
{2k \le n \le m aralığında n dəyərini ikili axtarışla tapın.
long long lo = 2*k, hi = m;
while (lo < hi)
{
long long n = (lo + hi) / 2;
if (Cnk(n,k) < m) lo = n + 1; else hi = n;
}C_{lo}^k = m olduqda həll tapılır. Nəticəyə bir və ya iki cüt həll daxil edin.
if (Cnk(lo,k) == m)
{
res.push_back(make_pair(lo,k));
if (lo != 2*k)
res.push_back(make_pair(lo,lo - k));
}
}Cütləri sırala.
sort(res.begin(),res.end());Cavabı çıxarın - tapılan cütlərin sayını və cütləri.
printf("%d\n",res.size());
for(i = 0; i < res.size(); i++)
printf("(%lld,%lld) ", res[i].first,res[i].second);
printf("\n");
}Binomial əmsal üçün asimptotik qiymətləndirmələr Teorema 1. Binomial əmsallar arasında belə bir əlaqə var:
C_n^0 < C_n^1 < ... < C_n^{\lfloor n/2 \rfloor} \ge C_n^{\lfloor n/2 \rfloor + 1} > ... > C_n^n
Teorema 2. C_{2n}^n < 4^n . Bu ondan irəli gəlir ki, \sum_{k = 0}^{2n} C_{2n}^k = (1 + 1)^{2n} = 2^{2n} = 4^n
Teorema 3. C_{2n}^n > {4^n \over 2n + 1} . Bu ondan irəli gəlir ki, \sum_{k = 0}^{2n} C_{2n}^k = 4^n , və əmsallar 2n + 1 -dir. Buna görə daha böyük əmsal {4^n \over 2n + 1} -dən çox olacaq.
Teorema 4. Stirlinq formulu. n! ≈ \sqrt{2 \pi n}\left({n \over e} \right) ^ n .
Daha dəqiq təxmini formulu:
n! ≈ \sqrt{2 \pi n} \left({n \over e} \right) ^ n \left( 1 + {1 \over 12n} + {1 \over 288n^2} - {139 \over 51849n^3} - {571 \over 2488320n^4} \right)
Teorema 5.
C_{2n}^n ≈ {\sqrt{4 \pi n}\left({2n \over e} \right) ^ {2n} \over \left( \sqrt{2 \pi n}\left({n \over e} \right) ^ n \right) ^2} = {4^n \over \sqrt{\pi n}}
Teorema 6.
C_n^k = {n! \over k!(n - k)!} = { n \cdot (n - 1) \cdot (n - 2) \cdot ... \cdot (n - k + 1) \over 1 \cdot 2 \cdot 3 \cdot ... \cdot k} =
{n! \over k!} \cdot \left( 1 - {1 \over n} \right) \cdot \left( 1 - {2 \over n} \right) \cdot ... \cdot \left( 1 - {k - 1 \over n} \right) =
{n! \over k!} \cdot e ^{ln \left( 1 - {1 \over n} \right) + ln \left( 1 - {2 \over n} \right) + ... + ln \left( 1 - {k - 1 \over n} \right)} \le (ln(1 - x) \le -x~neqali~vasitəsilə)
{n! \over k!} \cdot e ^{-{1 \over n} - {2 \over n} - ... - {k - 1 \over n}} = {n! \over k!} \cdot e^{-{k \cdot (k - 1) \over 2n}}
İstifadə olunan məsələlərin siyahısı
Şərhlər