騰訊2018秋招筆試真題-小Q的歌單
阿新 • • 發佈:2018-12-26
小Q的歌單
【題目描述】小 Q 有 X 首長度為 A 的不同的歌和 Y 首長度為 B 的不同的歌,現在小 Q 想用這些歌組成一個
總長度正好為 K 的歌單,每首歌最多隻能在歌單中出現一次,在不考慮歌單內歌曲的先後順序的情況下,
請問有多少種組成歌單的方法。
輸入描述:
每個輸入包含一個測試用例。
每個測試用例的第一行包含一個整數,表示歌單的總長度 K(1<=K<=1000)。
接下來的一行包含四個正整數,分別表示歌的第一種長度 A(A<=10)和數量 X(X<=100)以及歌的第二種長度
B(B<=10)和數量 Y(Y<=100)。保證 A 不等於 B。
輸出描述:
輸出一個整數,表示組成歌單的方法取模。因為答案可能會很大,輸出對 1000000007 取模的結果。
輸入示例:
5
2 3 3 3
輸出示例:
9
解題思路:
1)歌單存在時要滿足的條件
i * a <= k && (k - a * i) % b == 0 && (k - a * i) / b <= y
2)需要用得到的公式:
從i個不同元素中,選擇j個的組合數目,記為c[i][j],則滿足
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j])
程式碼
#include <stdio.h>
#include<stdlib.h> //system()
using namespace std;
long long c[105][105 ];
const int mod = 1000000007;
void init() {
c[0][0] = 1;
for (int i = 1; i <= 100; i++) {
c[i][0] = 1;
for (int j = 1; j <= 100; j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
int main() {
int k, a, b, x, y;
long long ans = 0;
init();
scanf_s("%d" , &k);
scanf_s("%d%d%d%d", &a, &x, &b, &y);
for (int i = 0; i <= x; i++) {
if (i * a <= k && (k - a * i) % b == 0 && (k - a * i) / b <= y)
ans = (ans + (c[x][i] * c[y][(k - a * i) / b]) % mod) % mod;
}
printf("%lld\n", ans);
system("pause");
return 0;
}
注:參考了牛客網解答。