给定n个球,球有m种颜色,其中m<=n,从n个球中取k个不同颜色的球,相同颜色的不同球算不同的取法,求取法有多少种。
可将颜色相同的球分为1组,总共n组,记相同颜色球的个数s[i]。例如3种颜色球个数是2、3、4,那么取3种颜色取法数就是2 * 3 * 4 = 24。
组合数递推公式:
C(n,m)=C(n-1,m-1)+C(n-1,m)
其中C(n, m)
是n中取m个数
递推式f[i][j]
表示前i
个数,取j
个得到的方案数之和。
已有f[i-1]
的答案,现在来了第i
个数,考虑取第i
个数和不取第i
个数。
取第i个数:第i个数可以和前面的f[i-1][j-1]
凑成j个数,f[i-1][j-1] * s[i]
不取第i个数:f[i-1][j]
二者取和,即f[i][j] = f[i-1][j-1] * s[i] + f[i-1][j]
最后求得f[n][k]
就是答案
例如现在有5个数2 3 4 5 6,那么2 3 4 5 6的第三行f[5][3]
就是f[4][2]*6 + f[4][3]
#include <iostream>
using namespace std;
int f[100][100], n, k, s[100];
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &s[i]);
f[i-1][0] = 1;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
f[i][j] = f[i-1][j] + f[i-1][j-1] * s[i];
}
}
printf("%d\n", f[n][k]);
}