小Q的歌單
1.問題描述:
小Q的歌單:
有X首長度爲a的歌和Y首長度爲b的歌,
現在需要組合有長度剛好是K的歌單
問有多少種組合方式,將結果模上1000000007
2.思路:
1.就是在長度爲a的選擇m首,在長度爲b的中選擇n首
2.計算其組合數即可
在這裏:組合數的求法:
(1)自己定義函數,按照公式求解即可。
(2)組合數就是楊輝三角,對應的組合數就是楊輝三角中二維數組的特定位置的元素。
3.代碼:
//小Q的歌單:
//有X首長度爲a的歌和Y首長度爲b的歌,
//現在需要組合有長度剛好是K的歌單
//問有多少種組合方式,將結果模上1000000007
//思路:
//1.就是在長度爲a的選擇m首,在長度爲b的中選擇n首
//2.計算其組合數即可
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000000007
//求組合數
//在a裏取b,有多少種方法
int com(int a, int b) {
//先判斷有沒有0操作數
if (a == 0 && b > a) {
return 0;
}
if (b > a) {
return 0;
}
if (b == 0 || b == a) {
return 1;
}
//利用公式 Cab == a!/(b! * (a-b)!);
int temp = a - b;
int suma = 1;
int sumb = 1;
int sumab = 1;
//求a的階乘
while (a) {
suma = suma * a;
a--;
}
// printf("suma = %d \n", suma);
while (b) {
sumb = sumb * b;
b--;
}
// printf("sumb = %d\n", sumb);
while (temp) {
sumab = sumab * temp;
temp--;
}
// printf("sumab = %d\n", sumab);
int ret = 0;
ret = suma / (sumb*sumab);
return ret % MAX;
}
int main() {
int x, a, y, b, k;
printf("請依次輸入:x首長度爲a,y首長度爲b,以及個單的長度k:\n");
scanf("%d%d%d%d%d", &x, &a, &y, &b, &k);
long long sum = 0; //用來記錄最後的大小
int i = 0;
while (i <= x) {
//符合準則的選擇方案
if (k - (a*i) >= 0 && (k - (a*i)) % b == 0 && (k-(a*i))/b <= y) {
long long p = com(x, i);
long long q = com(y, (k - (a*i)) / b);
sum += p * q;
sum %= MAX;
}
++i;
}
printf("%lld\n", sum);
system("pause");
return 0;
}