题目描述
设S是一个具有n个元素的集合,S={a1,a2,……,an},现将S划分成k个满足下列条件的子集合S1,S2,……,Sk ,且满足:

则称S1,S2,……,Sk是集合S的一个划分。它相当于把S集合中的n个元素a1 ,a2,……,an 放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空。请你确定n个元素a1 ,a2 ,……,an 放入k个无标号盒子中去的划分数S(n,k)对1e9+7取余之后的值。
输入n,k
输出S(n,k) mod 1e9+7 的值
样例输入 Copy
23 7
样例输出 Copy
968438818
AC代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<string>
const long long MOD=1e9+7;
using namespace std;
long long n,m,k;
long long dp(int n,int k)//i个数放进k个集合的总方案数
{
if(n==0 || n<k)//数小于集合数||没有数了,不存在方案
return 0;
if(n==k || k==1)//因为无标号,所以哪个盒子无所谓,盒子数=数,一个盒子,都是一种情况
return 1;
return (dp(n-1,k-1)+k*dp(n-1,k))%MOD;//要么单独是一个集合,所以相当于少一个数少一个集合
//要么这个数是从k个集合中取出来的,所以有k种选择(随便进哪个集合)
//相加的总和就是现在的方案数
}
int main()
{
cin>>n>>k;
cout<<dp(n,k)<<endl;
return 0;
}
本文介绍了一种计算给定集合S的元素按指定条件划分为k个非空子集的方案数S(n,k),并提供了使用动态规划求解的AC代码,着重于理解递归公式和对1e9+7取余操作的应用。
4063

被折叠的 条评论
为什么被折叠?



