小 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
思路:按排列組合的方式來做這道題的話,思路會比較清晰。是這樣的:我們將兩種長度的歌的數量進行遍歷,如果滿足總長度爲K的話,就去算該數量的組合方式下共有多少種不同的歌曲的組合方式。於是這道題就變成了簡單的高中數學問題,也就是怎麼求組合,那麼寫一個算組合的函數,這道題就解出來了。
int c(int son, int mother) //C上面和下面
{
int up = 1, down = 1;
if (mother<son || son<0)
return 0;
if (son > (mother >> 2)) //C(3,8) == C(5,8)
son = mother - son;
if (son == 0)
return 1;
for (int i = 0; i<son; i++)
{
up *= (mother-i);
down *= (i+ 1);
}
return (up / down);
}
long tengxun_xiaoQdegedan(int x, int xn, int y,int yn, int k)
{
long mod = 1000000007;
assert(x > 0 && y > 0 && k > x && k > y && xn > 0 && yn>0 && x!=y);
long res = 0;
for (int i = 0; i < xn; i++)
{
for (int j = 0; j < yn; j++)
{
if (x*i + y*j == k)
res += c(i, xn)*c(j, yn);
}
}
return (res % mod);
}