题解 P2028 【龙兄摘苹果】

题目

题意简述

\(n\) 个元素分成 \(k\) 个非空集合的方案数(集合内无序),即 \(S(n,k)\)

推导过程

  1. 如果前 \(n-1\) 个元素组成了 \(k-1\) 个非空集合,那么第 \(n\) 个元素自然成为第 \(k\) 个非空集合。
  2. 如果前 \(n-1\) 个元素组成了 \(k\) 个非空集合,那么第 \(n\) 个元素可以放进这 \(k\) 个非空集合中的任意一个。

递推式

由推导过程可以得出递推式,\(S(i,j) = S(i-1,j-1) + S(i-1,j)*j\)

需要注意的是,由于数据范围很大,除了要开 unsigned long long ,递推的过程中还必须时刻取模!!!

Code:

#include<bits/stdc++.h>
using namespace std;
unsigned long long f[10005][1005];
long long n,k,p;
int main()
{
    cin>>n>>k>>p;
    f[1][1] = 1;
    for(int i=1;i<=n;i++)  //为了省略重置 S(1,j) 的循环步骤
    {
        f[i][1] = 1;     //无论多少个元素,当要组成1个集合时,只有一种办法 
        for(int j=1;j<=k;j++)
        {
            f[i][j] = (f[i-1][j-1]%p + (f[i-1][j]%p)*(j%p))%p;   //递推式,注意取模 
            f[1][1] = 1;   //填坑 
        }
    }
    cout<<f[n][k];  //输出
    return 0;
}
posted @ 2021-05-01 15:54  我和鱼过不去  阅读(71)  评论(0)    收藏  举报