链接:https://www.nowcoder.com/questionTerminal/f3ab6fe72af34b71a2fd1d83304cbbb3
来源:牛客网
小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取模的结果。
示例1
输入
5 2 3 3 3
输出
9
因为只有两个数 所以必然有 a*x+b*y=k 这个恒成立
所以每次我们都是从 x 里面选出 n个a 和从y里面选出 m个b 我们只需要枚举 n的个数然后每次 求组合数 C(x,n)*C(y,m)
杨辉三角的性质就是求组合数
#include<bits/stdc++.h> using namespace std; #define LL long long const LL mod = 1000000007; int dp[205][205]; void init(){ dp[0][0]=1; for(int j=1;j<=100;j++){ dp[j][0]=1; for(int k=1;k<=100;k++){ dp[j][k]=(dp[j-1][k-1]+dp[j-1][k])%mod; } } } int main(){ init(); int k,a,x,b,y; cin>>k>>a>>x>>b>>y; LL ans=0; for(int j=0;j<=x;j++){ if(a*j<=k&&(k-a*j)/b<=y&&(k-a*j)%b==0){ ans+=dp[x][j]*dp[y][(k-a*j)/b]%mod; ans%=mod; } } cout<<ans<<endl; }