騰訊筆試—— 小 Q 的歌單 【 題目描述】小 Q 有 X 首長度爲 A 的不同的歌和 Y 首長度爲 B 的不同的歌,現在小 Q 想用這些歌組成一個 總長度正好爲 K 的歌單,每首歌最多隻能在歌單中

小 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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章