题目:自然的雪糕

题目描述

题目背景
话说某天小岛从超市里买了许许多多的..雪糕....本来他打算存在冰箱里慢慢享用的...
结果这件事情被寝室里的adx发现了...于是不幸的事情发生了...

题目叙述
小岛回忆起了当时de场景...
那时...寝室里包括自己一共聚集了 n 个人...我从超市里共买了 m 袋不同种类的雪糕.....
醒来之后身边一支雪糕也没有了.....我还可以隐约知道...每个人都不会一支雪糕也不拿...
小岛想知道自己的雪糕现在会在哪...那么当时的情况下...一共有多少种不同的可能呢..?

数据规模
对于30% 的数据,n <= 10,m <= 20。
对于100%的数据, n <= 100,m<= 100。

样例解释
雪糕以 1-3 编号。共六种情况,其中三种为:
1. {1} {2, 3}
2. {2} {1, 3}
3. {3} {1, 2}
另三种与之对称。

输入格式

一行两个数 n,m...

输出格式

一个数表示当时可能的情况数目...

第二类斯特林数。

s(n,k)表示将n个不同物体放在k个一样的盘子上(每份>0个)的方法数。

s(n,k)=k*s(n-1,k)+s(n-1,k-1);

s(m,n-1)*(n-1)!就是本题答案。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int n,m,s[105][105][205],d[205],ans[205];
 5 bool flag[105][105];
 6 
 7 void S(int x,int y){
 8      if(flag[x][y]||x<y||y==0) return ;
 9      if(y==1||x==y) {s[x][y][0]=1;flag[x][y]=1;return ;}
10      
11      S(x-1,y);
12      S(x-1,y-1);
13      for(int i=0;i<200;++i)
14      s[x][y][i]=y*s[x-1][y][i];
15      for(int i=0;i<200;++i)
16      s[x][y][i]+=s[x-1][y-1][i];
17      for(int i=0;i<200;++i)
18      if(s[x][y][i]>9) 
19      s[x][y][i+1]+=s[x][y][i]/10,s[x][y][i]%=10;
20      flag[x][y]=1;
21      return ;
22      }
23 
24 int main()
25 {
26     cin>>n>>m;
27     n--;
28     
29     S(m,n);
30     
31     d[0]=1;
32     for(int i=1;i<=n;++i)
33     {
34       for(int k=0;k<200;++k)
35       d[k]*=i;   
36       for(int k=0;k<200;++k)
37       if(d[k]>9) d[k+1]+=d[k]/10,d[k]%=10;
38             }
39     
40     for(int i=0;i<200;++i)
41     for(int j=0;j<200-i;++j)
42     {
43       ans[i+j]+=d[i]*s[m][n][j];
44       if(ans[i+j]>9)
45       {ans[i+j+1]+=ans[i+j]/10;ans[i+j]%=10;}       
46             }
47     
48             
49     int i=199;
50     while(ans[i]==0&&i>0) i--;
51     while(i>=0) cout<<ans[i--];
52     cout<<endl;
53    // system("pause");
54     return 0;
55     
56     }
原文地址:https://www.cnblogs.com/noip/p/2713312.html