n个元素的集合有多少个划分

复习离散时看见这个问题就想着写一下

思路:

将问题转化为再原有划分的基础上,增加一个元素,有多少种可能。将n个元素划分成m个元素,可以转化为,由n-1和m-1的划分加上一个单独的元素,或n-1和m的划分,这时可以理解成,将新添加的元素加到m个集合中的一个。

贴一个newbing的解释:

5个元素的集合共有不同的划分数为 52 。这个问题可以转化为将一个5元素集合划分成1个或多个非空子集的问题。我们可以使用斯特林数来计算这个问题的答案。斯特林数是将n个不同的元素划分成k个非空集合的方案数,记作S(n,k)。对于这个问题,我们需要计算S(5,1)+S(5,2)+S(5,3)+S(5,4)+S(5,5)的值,其中S(n,k)的值可以使用递推公式或者递归公式来计算。根据斯特林数的定义,我们可以得到:

S(n,k)=S(n-1,k-1)+(n-1)*S(n-1,k)

其中,当k=0或n<k时,S(n,k)=0;当k=1时,S(n,k)=1。

因此,我们可以得到:

S(5,1)=1

S(5,2)=6

S(5,3)=25

S(5,4)=50

S(5,5)=24

因此,5个元素的集合共有不同的划分数为:

S(5,1)+S(5,2)+S(5,3)+S(5,4)+S(5,5)=1+6+25+50+24=52

代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
map<pair<long long, long long>, long long> dp;
long long F(long long n, long long m)
{
	if (m == 1)
	{
		return 1;
	}
	if (m == n)
	{
		return 1;
	}
	if (dp.find({ n,m }) != dp.end())
	{
		return dp[{n, m}];
	}
	dp[{n, m}] = F(n - 1, m - 1) + m * F(n - 1, m);
	return dp[{n, m}];
}
int main()
{
	long long n;
	cin >> n;
	long long ans = 0;
	for (int i = 1; i <= n; i++)
	{
		ans += F(n, i);
	}
	cout << ans << endl;
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值