您的位置:首页 > 编程语言 > C语言/C++

不是你想象中的组合数计算

2018-03-05 23:41 176 查看
我们印象中计算组合数的公式

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


数学和计算机是紧密联系的,大家要多多思考
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 数学