zoukankan      html  css  js  c++  java
  • 【NOIP2017提高A组模拟9.17】组合数问题

    【NOIP2017提高A组模拟9.17】组合数问题

    题目

    Description

    定义"组合数"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.

    Input

    从problem.in 种读入数据第一行有两个整数t,k,t 代表该测试点总共有多少组测试数据.接下来t 行,每行两个整数n,m.

    Output

    输出到文件problem.out 中t 行,每行一个整数代表所有的0<=i<=n,0<=j<=min(i,m),有多少对(i,j),满足S(i,j)是k 的倍数.

    Sample Input

    输入1:
    1 2
    3 3
    输入2:
    2 5
    4 5
    6 7

    Sample Output

    输出1:
    3
    样例说明1:S(1,0),S(2,0),S(3,0)均是2 的倍数
    输出2:
    4
    12

    Data Constraint

    对于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

    题解

    第二类斯特林数
    公式:
    (S(i,j)=S(i-1,j-1)+j*S(i-1,j))
    证明

    1. 当前这个元素新开一个集合,(S(i-1,j-1))
    2. 当前这个元素进入一个原本存在的集合 (j*S(i-1,j-1))

    根据加法定理,两者相加就是答案
    预处理的同时(\%k)
    然后用二维前缀和统计0的个数

    Code

    #include<cstdio>
    #include<iostream>
    #define ull unsigned long long
    using namespace std;
    int t,k,k1,n,m,c[2001][2001],s[2001][2001];
    int read()
    {
    	int res=0;char ch=getchar();
    	while (ch<'0'||ch>'9') ch=getchar();
    	while (ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch-'0'),ch=getchar();
    	return res;
    }
    int main()
    {
    	freopen("problem.in","r",stdin);
    	freopen("problem.out","w",stdout);
    	t=read();k=read();
    	c[1][1]=c[0][0]=1;
    	for (int i=2;i<=2000;++i)
    		for (int j=1;j<=min(2000,i);++j)
    			c[i][j]=(c[i-1][j-1]%k+j*c[i-1][j]%k)%k;
    	for (int i=0;i<=2000;++i)
    		for (int j=0;j<=i;++j)
    			if (c[i][j]==0) s[i][j]=1;
    	for (int i=1;i<=2000;++i)
    		s[i][0]+=s[i-1][0],s[0][i]+=s[0][i-1];
    	for (int i=1;i<=2000;++i)
    		for(int j=1;j<=2000;++j)
    			s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
    	while (t--)
    	{
    		n=read();m=read();
    		printf("%d
    ",s[n][m]);
    	}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;	
    } 
    
  • 相关阅读:
    影响CSS的margin合并的几个属性
    Mouse w/o Borders实现两台主机共用一套键鼠方法及问题处理
    隐藏"Input"标签默认样式
    如何快速开发网站?
    如何让Web.xml变得简洁?
    关于中文处理方面的研究
    Hello,World 百态
    UI开发的终极解决方案
    构建网络爬虫?so easy
    MDA数据校验规则定义
  • 原文地址:https://www.cnblogs.com/Livingston/p/14016036.html
Copyright © 2011-2022 走看看