Birləşdirilmiş ardıcıllığı nəzərdən keçirək:
Onun uzunluğu -ə bərabərdir. Məsələnin şərtindən aydın olur ki, bu ardıcıllıq:
artmayan sıralama qaydasında;
-dən -ə qədər olan ədədlərdən ibarətdir.
Deməli, məsələ aşağıdakı artmayan ardıcıllıqların sayını hesablamağa çevrilir:
Değişkenlərin dəyişməsini həyata keçirək:
O zaman bütün y_i \ge 0, və onların cəmi aydın olur ki
Beləliklə, bu problem n - 1 ədədini 2m + 1 qeyri-mənfi tam əlavələrə bölmənin sayını hesaplamaya çevrilir. Belə bölmələrdən hər birinə dəqiq bir artmayan ardıcıllıq x_1, x_2, ..., x_{2m} uyğun gəlir, buna görə də dəqiq bir cüt array uyğun gəlir.
Təkrarlı birləşmələrin klassik formuluna görə belə bölmələrin sayı C_{n+2m-1}^{2m}-ə bərabərdir (bax Eolimp məsələsi ).
Misal
Birinci testdə uyğun variant var:
a = [1, 1], b = [2, 2];
a = [1, 2], b = [2, 2];
a = [2, 2], b = [2, 2];
a = [1, 1], b = [2, 1];
a = [1, 1], b = [1, 1]
Uyğun birləşdirilmiş ardıcıllıq aşağıdakı bərabərsizliyin şərtlərini ödəmiş olur:
Değişkenlərin dəyişməsini həyata keçirək:
Değmək dəyişənləri cəmləyək:
Bu bərabərliyin həlli var. Onlardan hər birində dəqiq bir dəyişən y_i-ə -ə bərabərdir, digər bütün dəyişənlər -a bərabərdir. Bu həllərin ilkin ardıcıllıqlara uyğun nəticələrini nəzərdən keçirək:
Alqoritmin reallaşdırması
dəyişəninin bir dəyişənini və massivi təyin edək, burada dp[n][k] = C_n^k.
#define MOD 1000000007
long long dp[3001][30];Cnk funksiyası binomial koeffisienti olan C_n^k-nin qiymətini hesablamaq üçün istifadə edilir.
long long 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)) % MOD;
}Proqramın əsas hissəsi. Verilənləri oxuyuruq.
scanf("%d %d", &n, &m);Müxtəlif -ni başlandığımız.
memset(dp, -1, sizeof(dp));Cavab C_{n+2m-1}^{2m}-nin hesablayıb və çıxarırıq.
printf("%d\n", Cnk(n + 2 * m - 1, 2 * m));