洛谷——P1655 小朋友的球

https://www.luogu.org/problem/show?pid=1655

题目描述

@发源于 小朋友最近特别喜欢球。有一天他脑子抽了,从口袋里拿出了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数,递推公式s[i][j]=s[i-1][j]*j+s[i-1][j-1]这个在各类组合数学书籍上均有证明,现截取一段

S(p,k)的一个组合学解释是:将p个物体划分成k个非空的不可辨别的(可以理解为盒子没有编号)集合的方法数。

k!S(p,k)是把p个人分进k间有差别(如:被标有房号)的房间(无空房)的方法数。

S(p,k)的递推公式是:S(p,k)=k*S(p-1,k)+S(p-1,k-1) ,1<= k<=p-1

边界条件:S(p,p)=1 ,p>=0 S(p,0)=0 ,p>=1

递推关系的说明:

考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的不可辨别的集合,方法数为S(p-1,k-1);

也可以前p-1种物品构成k个非空的不可辨别的集合,第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。

注意:当m>n||m==0时直接输出0,!

*/

不用高精20分。

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 using namespace std;
 6 
 7 int n,m,f[110][110];
 8 
 9 int main()
10 {
11     for(int i=0;i<=100;i++) f[i][i]=1;
12     for(int i=1;i<=100;i++)
13         for(int j=1;j<=i;j++)
14             f[i][j]=f[i-1][j-1]+f[i-1][j]*j;
15     for(;~scanf("%d%d",&n,&m);)
16     {
17         if(!m||m>n) puts("0");
18         else printf("%d\n",f[n][m]);
19     }
20     return 0;
21 }
20

 

 初值 f[1][1]=1   从2开始枚举

高精AC

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 using namespace std;
 6 
 7 int n,m;
 8 struct Gj
 9 {
10     int num[555];
11     Gj() { for(int i=1;i<=500;i++) num[i]=0;num[0]=1; }
12     void print() { for(int i=num[0];i;i--) printf("%d",num[i]); }
13 }f[110][110];
14 Gj mul(Gj a,int x)
15 {
16     for(int ove=0,i=1;i<=a.num[0];i++)
17     {
18         a.num[i]=a.num[i]*x+ove;
19         if(a.num[i]>9)
20         {
21             ove=a.num[i]/10;
22             a.num[i]%=10;
23             a.num[0]=max(a.num[0],i+1);
24         }
25         else ove=0;
26     }
27     for(;!a.num[a.num[0]]&&a.num[0];) a.num[0]--;
28     return a;
29 }
30 Gj add(Gj a,Gj b)
31 {
32     Gj c;
33     c.num[0]=max(a.num[0],b.num[0]);
34     for(int i=1,x=0;i<=c.num[0];i++)
35     {
36         c.num[i]=a.num[i]+b.num[i]+x;
37         if(c.num[i]>9)
38         {
39             x=c.num[i]/10;
40             c.num[i]%=10;
41             c.num[0]=max(i+1,c.num[0]);
42         }
43         else x=0;
44     }
45     for(;!c.num[c.num[0]]&&c.num[0];) c.num[0]--;
46     return c;
47 }
48     
49 int main()
50 {
51 //    for(int i=0;i<=100;i++) f[i][i].num[1]=1;
52     f[1][1].num[1]=1;
53     for(int i=2;i<=100;i++)
54         for(int j=1;j<=i;j++)
55         {
56             Gj tmp=mul(f[i-1][j],j);
57             f[i][j]=add(tmp,f[i-1][j-1]);
58         }
59     for(;~scanf("%d%d",&n,&m);)
60         f[n][m].print(),printf("\n");
61     return 0;
62 }

 

posted @ 2017-08-10 21:14  Aptal丶  阅读(204)  评论(0编辑  收藏  举报