Description
Input
Output
Sample Input
4 1 2 3 100
Sample Output
1 2 5 751
经典贝尔数题,本代码是根据贝尔三角数列做的,每个位置上的数都等于它左边及左上角的数之和。
AC代码如下:
#include<stdio.h> #include<string.h> #define M 2000 int a[2001][2001]; int main() { memset(a,0,sizeof(a)); int i,j; a[1][1]=1;a[2][1]=1; for(i=2;i<=M;i++) { a[i][1]=a[i-1][i-1]; for(j=2;j<=M;j++) a[i][j]=(a[i][j-1]+a[i-1][j-1])%1000; } int n,m; scanf("%d",&n); while(n--) { scanf("%d",&m); printf("%d\n",a[m][m]); } return 0; }
这类组合问题用第二类斯特灵数可以解决
S(P,K)=S(P-1,K-1)+K*S(P-1,K);表示P个元素放入K个不可区分的集合中而且集合不为空的划分个数。
那么问题的解为sigma(S(P,i)) (P=>i>=1) 这个和称为bell数。
Bell数是将P个元素集合分到非空且不可区分例子的划分个数
一个典型的动态规划,比较复杂点的排列组合,
首先就是把第n个一卡通放入书中,第一种就是放在另外一本书中,就相当于把n-1个一卡通放入j-1本书中,就是a[i-1][j-1]个
然后就是把这个卡插到原来的书中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int a[2001][2001],b[2002]; int main() { int t,i,j,n,x; memset(b,0,sizeof(b)); for(i=1; i<2001; i++) a[i][i]=a[i][1]=1; for(i=2; i<2001; i++) for(j=2; j<=i; j++) a[i][j]=(a[i-1][j-1]+a[i-1][j]*j)%1000; for(i=1; i<2001; i++) for(j=1;j<=i;j++) b[i]+=a[i][j]; scanf("%d",&n); while(n--) { scanf("%d",&x); printf("%d\n",b[x]%1000); } return 0; }