题目描述
@发源于 小朋友最近特别喜欢球。有一天他脑子抽了,从口袋里拿出了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。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,f[110][110]; int stirling(int a,int b){ if(f[a][b]!=-1)return f[a][b]; if(b==0)return f[a][b]=0; if(a==b)return f[a][b]=1; if(a==0)return f[a][b]=0; return f[a][b]=b*stirling(a-1,b)+stirling(a-1,b-1); } int main(){ memset(f,-1,sizeof(f)); while(scanf("%d%d",&n,&m)!=EOF){ printf("%d ",stirling(n,m)); } }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[1000],b[1000],c[1000]; int n,m; struct node{ int len,zu[1000]; node operator + (const node x)const{ memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); for(int i=1,j=len;i<=len;i++,j--)a[i]=zu[j]; for(int i=1,j=x.len;i<=x.len;i++,j--)b[i]=x.zu[j]; int l=max(len,x.len); for(int i=1;i<=l;i++){ c[i]+=a[i]+b[i]; c[i+1]+=c[i]/10; c[i]=c[i]%10; } while(c[l+1]){ l++; c[l+1]+=c[l]/10; c[l]%=10; } node res; res.len=l; for(int i=1,j=l;i<=l;i++,j--)res.zu[i]=c[j]; return res; } node operator * (const int x)const{ memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(int i=1,j=len;i<=len;i++,j--)a[i]=zu[j]; int l=len; for(int i=1;i<=l;i++){ b[i]+=a[i]*x; b[i+1]+=b[i]/10; b[i]%=10; } while(b[l+1]){ l++; b[l+1]+=b[l]/10; b[l]=b[l]%10; } node res; res.len=l; for(int i=1,j=l;i<=l;i++,j--)res.zu[i]=b[j]; return res; } }f[110][110]; node stirling(int x,int y){ if(f[x][y].len!=0)return f[x][y]; if(x==0||y==0){ f[x][y].len=1; f[x][y].zu[1]=0; return f[x][y]; } if(x==y){ f[x][y].len=1; f[x][y].zu[1]=1; return f[x][y]; } f[x][y]=stirling(x-1,y)*y+stirling(x-1,y-1); return f[x][y]; } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ node ans=stirling(n,m); for(int i=1;i<=ans.len;i++)printf("%d",ans.zu[i]); printf(" "); } }