zoukankan      html  css  js  c++  java
  • 斯特林数

    洛谷P1655 小朋友的球

    题目描述

    @发源于 小朋友最近特别喜欢球。有一天他脑子抽了,从口袋里拿出了N个不同的球,想把它们放到M个相同的盒子里,并且要求每个盒子中至少要有一个球,他好奇有几种放法,于是尝试编程实现,但由于他天天不好好学习,只会上B站看游泳教练,于是他向你求助。

    输入输出格式

    输入格式:

     

    多组数据,每行两个数N,M。

     

    输出格式:

     

    每组数据一行,表示方案数。

     

    输入输出样例

    输入样例#1:
    4 2
    1 1
    输出样例#1:
    7
    1

    说明

    【样例解释】

    N=4,M=2

    1,2 3 4

    2,1 3 4

    3,1 2 4

    4,1 2 3

    1 2,3 4

    1 3,2 4

    1 4,2 3

    对于20%的数据,满足1≤N,M≤10;

    对于100%的数据,满足1≤N,M≤100,数据组数≤10。



    stirling数

    斯特林数解决的是这样一个问题:
    n个不相同的元素,分割为m个集合,每个集合非空【至少有一个元素】,集合无序,问有多少种分割方法?
    其实就是题目所述的分球问题

    我们令f(n,m)为答案,根据dp的思想,对于第i个球,要么单独放一个盒子,要么在前i-1个球放完后加入其中一个盒子
    那么就有f(n,m)=f(n-1,m-1)+j*f(n-1,m)
    边界f(i,i)=1,i>=0
    f(i,0)=0,i>=1
    那么加上高精度就可以解了


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #define LL long long int
    using namespace std;
    const int maxn=105,INF=2000000000;
    
    int N,M;
    
    class BIG{
    	public:
    		int n[maxn],len;
    		BIG() {memset(n,0,sizeof(n));len=0;}
    }dp[maxn][maxn];
    
    istream& operator >>(istream& in,BIG& a){
    	string s;
    	in>>s;
    	a.len=s.length();
    	for(int i=0;i<a.len;i++) a.n[i]=s[a.len-i-1]-'0';
    	return in;
    }
    
    ostream& operator << (ostream& out,const BIG& a){
    	if(!a.len) cout<<0;
    	for(int i=a.len-1;i>=0;i--) out<<a.n[i];
    	return out;
    }
    
    BIG operator + (const BIG& a,const BIG& b){
    	BIG c;
    	c.len=max(a.len,b.len);
    	int carry=0,temp;
    	for(int i=0;i<c.len;i++){
    		temp=a.n[i]+b.n[i]+carry;
    		c.n[i]=temp%10;
    		carry=temp/10;
    	}
    	if(carry) c.n[c.len++]=carry;
    	return c;
    }
    
    BIG operator * (const BIG& a,const int& b){
    	int carry=0,temp;
    	BIG c;
    	c.len=a.len;
    	for(int i=0;i<a.len;i++){
    		temp=a.n[i]*b+carry;
    		c.n[i]=temp%10;
    		carry=temp/10;
    	}
    	while(carry) c.n[c.len++]=carry%10,carry/=10;
    	return c;
    }
    
    int main()
    {
    	for(int i=0;i<=100;i++){
    		dp[i][i].len=dp[i][i].n[0]=1;
    	}
    	for(int i=1;i<=100;i++)
    		for(int j=1;j<=i;j++){
    			dp[i][j]=dp[i-1][j]*j+dp[i-1][j-1];
    		}
    	while(cin>>N>>M) cout<<dp[N][M]<<endl;
    	return 0;
    }
    




  • 相关阅读:
    安装win7 ubuntu双系统
    idea maven打jar包
    mongodb入门
    mongodb备份与恢复
    使用cmd时cd命令失效
    vue 项目中使用阿里巴巴矢量图标库iconfont
    vue img标签用法
    vue 点击当前元素改变样式
    vue 路由跳转传参
    iview table绑定双击事件
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282888.html
Copyright © 2011-2022 走看看