集合划分-递归分治

题目

集合划分:
给一个有 n 个元素的集合,将它划分为多个非空子集(可以包含自己),问有多少种划分?

样例输入

4

样例输出

15

样例解释

输入为 n ,表示集合有n个元素
输出为15 ,表示有15种划分:
{{1},{2},{3},{4}},
——————————————————
{{1,2},{3},{4}},
{{1,3},{2},{4}},
{{1,4},{2},{3}},
{{2,3},{1},{4}},
{{2,4},{1},{3}},
{{3,4},{1},{2}},
——————————————————
{{1,2},{3,4}},
{{1,3},{2,4}},
{{1,4},{2,3}},
——————————————————
{{1,2,3},{4}},
{{1,2,4},{3}},
{{1,3,4},{2}},
{{2,3,4},{1}},
——————————————————
{{1,2,3,4}}

分析

  1. 因为是集合,因此不用考虑是否会有重复的元素出现。(集合的性质)
  2. 将 n 元素划分,可以划分为1~ n 组。
  • 如果划分为1组,那一个组就有 n 个元素;
  • 如果划分为 n 组,那么每组就是一个元素。
    如果我们能设计出将 n 元素划分为 m 组的函数f(n,m),外面嵌套一个对 m 的 for 循环就可以了。
  1. 假设将一个 n 元素划分为一个 m 组:
    (1)如果 n = 1 ,说明只有一个元素,则只能划分为一个组
    (2)如果 m = 1 ,说明划分为1组,则也只有一种划分。
    (3)如果 n = m ,将 n 个元素划分为 n 组,肯定也只有一种划分。
    (4)else:这里可以采用分治递归的方式解决:
    ”将 n 个元素划分为 m 组 “可以分成下面两种情况:
    ①如果第 n 号元素被单独分为了一组,那接下来就是需要将1~ n-1 个元素划分为 m-1 组。f(n,m)=f(n-1,m-1)
    ②如果第 n 号元素没有被单独分为了一组,接下来就是需要把 1~ n-1 个元素划分为 m 组,把 n 号元素插入到 m 组中的其中一组中去。f(n,m)=m*f(n-1,m)

AC代码

#include<iostream>
using namespace std;
long f(int n,int i) {//将n个数划分为i组 会有多少种划分?? 
	if(i==1||n==i)//如果划分为n组 或者划分为1组 则均只有一种划分 
		return 1;
	return f(n-1,i-1)+i*f(n-1,i);
	//将n号元素单独为一组,剩下1~n-1个元素为i-1组
	//不将n个元素单独为一组:
	//将1~n-1个元素分为i组,将n号元素插入到其中某一组中去,
	//插到哪组呢?有i种插法,因此需要乘i 
}
int main() {
	int n,sum=0;
	cin>>n;
	for(int i=1; i<=n; i++)
		sum+=f(n,i);
	cout<<sum;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MORE_77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值