我们印象中计算组合数的公式
C(kn)=A(kn)A(kk)
但其实,还有另外一个,常见于编程使用
C(kn)=C(k−1n−1)+C(kn−1)
Problem:挑选子集
Description
给定N个整数A1, A2, … AN,小Hi希望从中选出M个整数,使得任意两个选出的整数的差都是K的倍数。
请你计算有多少种不同的选法。由于选法可能非常多,你只需要输出对1000000009取模的结果。
Input
第一行包含三个整数N、M和K。
第二行包含N个整数A1, A2, … AN。
对于30%的数据,2 ≤ M ≤ N ≤ 10
对于100%的数据,2 ≤ M ≤ N ≤ 100 1 ≤ K, Ai ≤ 100
Sample Input
5 3 2
1 2 3 4 5
Sample Output
1
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
const int mod =1000000009;
int c[101][101];//记录组合数
int cnt[101];//记录模k的余数
int main()
{
int n,m,k,x;
cin>>n>>m>>k;
for(int i=0;i<n;++i){
cin>>x;
x%=k;
cnt[x]++;
}
c[0][0]=1;
for(int i=1;i<=n;++i){
c[i][0]=1;
for(int j=1;j<=i;++j){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
}
ll ans=0;
for(int i=0;i<k;++i){
if(cnt[i]>=m)
ans += c[cnt[i]][m];
}
ans %= mod;
if(ans<0)
ans += mod;
cout<<ans<<endl;
return 0;
}
数学和计算机是紧密联系的,大家要多多思考