1. 程式人生 > >騰訊2018秋招筆試真題-小Q的歌單

騰訊2018秋招筆試真題-小Q的歌單

小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; }

注:參考了牛客網解答。