组合数问题(zyys版)
2017-09-30 15:06
155 查看
【问题描述】
定义"组合数"S(n,m)代表将 n 个不同的元素拆分成 m 个非空集合的方案
数.举个栗子,将{1,2,3}拆分成 2 个集合有({1},{2,3}),({2},{1,3}),({3},{1,2})三种拆分
方法.
小猫想知道,如果给定 n,m 和 k,对于所有的 0<=i<=n,0<=j<=min(i,m),有多少对
(i,j),满足 S(i,j)是 k 的倍数.
注意,0 也是 k 的倍数,S(0,0)=1,对于 i>=1,S(i,0)=0.
【输入格式】
从 problem.in 种读入数据
第一行有两个整数 t,k,t 代表该测试点总共有多少组测试数据.
接下来 t 行,每行两个整数 n,m.
【输出格式】
输出到文件 problem.out 中
t 行,每行一个整数代表所有的 0<=i<=n,0<=j<=min(i,m),有多少对(i,j),满足 S(i,j)
是 k 的倍数.
【样例输入 1】
12
33
【样例输出 1】
3
【样例说明 1】
S(1,0),S(2,0),S(3,0)均是 2 的倍数
【样例输入 2】
25
45
67
【样例输出 2】
4
12
【数据规模与约定】
对于 20%的数据,满足 n,m<=7,k<=5
对于 60%的数据,满足 n,m<=100,k<=10
对于每个子任务,都有 50%的数据满足 t=1
对于 100%的数据,满足 1<=n<=2000,1<=m<=2000,2<=k<=21,1<=t<=10000
[b]斯特林数[/b](II)
[b]S[i][j]=S[i-1][j-1]+j*S[i-1][j][/b]
[b]解释一下:[/b]
[b]对于i,j,它可以单独构成j集合,前面要有j-1个集合[/b]
[b]也可以放入前面的集合
[/b]
[b]因为集合非空,所以前面的集合要有j个,有j种选择[/b]
定义"组合数"S(n,m)代表将 n 个不同的元素拆分成 m 个非空集合的方案
数.举个栗子,将{1,2,3}拆分成 2 个集合有({1},{2,3}),({2},{1,3}),({3},{1,2})三种拆分
方法.
小猫想知道,如果给定 n,m 和 k,对于所有的 0<=i<=n,0<=j<=min(i,m),有多少对
(i,j),满足 S(i,j)是 k 的倍数.
注意,0 也是 k 的倍数,S(0,0)=1,对于 i>=1,S(i,0)=0.
【输入格式】
从 problem.in 种读入数据
第一行有两个整数 t,k,t 代表该测试点总共有多少组测试数据.
接下来 t 行,每行两个整数 n,m.
【输出格式】
输出到文件 problem.out 中
t 行,每行一个整数代表所有的 0<=i<=n,0<=j<=min(i,m),有多少对(i,j),满足 S(i,j)
是 k 的倍数.
【样例输入 1】
12
33
【样例输出 1】
3
【样例说明 1】
S(1,0),S(2,0),S(3,0)均是 2 的倍数
【样例输入 2】
25
45
67
【样例输出 2】
4
12
【数据规模与约定】
对于 20%的数据,满足 n,m<=7,k<=5
对于 60%的数据,满足 n,m<=100,k<=10
对于每个子任务,都有 50%的数据满足 t=1
对于 100%的数据,满足 1<=n<=2000,1<=m<=2000,2<=k<=21,1<=t<=10000
[b]斯特林数[/b](II)
[b]S[i][j]=S[i-1][j-1]+j*S[i-1][j][/b]
[b]解释一下:[/b]
[b]对于i,j,它可以单独构成j集合,前面要有j-1个集合[/b]
[b]也可以放入前面的集合
[/b]
[b]因为集合非空,所以前面的集合要有j个,有j种选择[/b]
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int k,t,n,m; long long S[2001][2001],a[2001][2001]; int main() {int i,j; cin>>t>>k; S[0][0]=1; for (i=1;i<=2000;i++) { S[i][0]=0; for (j=1;j<=i;j++) { S[i][j]=(S[i-1][j-1]+S[i-1][j]*j)%k; } } for (i=0;i<=2000;i++) { for (j=0;j<=i;j++) { if (S[i][j]==0) a[i][j]=1; } } for (i=1;i<=2000;i++) { for (j=1;j<=2000;j++) a[i][j]+=a[i][j-1]; } for (i=1;i<=2000;i++) { for (j=0;j<=2000;j++) a[i][j]+=a[i-1][j]; } while (t--) { scanf("%d%d",&n,&m); printf("%lld\n",a [m]); } }
相关文章推荐
- [BZOJ4870][六省联考2017]组合数问题(组合数动规)
- UOJ263 【NOIP2016】组合数问题
- 洛谷 P2822 组合数问题
- 【NOIP2016】D2 T1 组合数问题
- 一道组合数问题
- bzoj4870 [Shoi2017]组合数问题
- 有关组合数越界的问题
- bzoj 4870: [Shoi2017]组合数问题 [矩阵乘法优化dp]
- bzoj4870: [Shoi2017]组合数问题(DP+矩阵乘法优化)
- bzoj4870&luogu3746 [六省联考2017]组合数问题
- 洛谷 P2822 组合数问题
- [DP 倍增] BZOJ 4870 [Shoi2017]组合数问题
- 回溯法之组合数问题
- 【bzoj 4870】组合数问题(DP+矩阵乘法)
- Noip2016 提高组 Day2 T1 组合数问题
- 【BZOJ4870】组合数问题(SHOI2017)-矩阵优化DP
- 组合数问题--------一种新的 搜索 思路
- NYOJ 组合数问题
- 组合数问题
- 【NOIP2016】 组合数问题