算法笔记 //06_集合划分问题

★问题描述

n 个元素的集合 {1,2,……, n } 可以划分为若干个非空子集。例如,当 n=4 时,集合 {1,2,3,4} 可以划分为 15 个不同的非空子集如下:
这里写图片描述

★编程任务

给定正整数 n,计算出 n 个元素的集合 {1,2,……, n } 可以划分为多少个不同的非空子集。

**

★算法思想

//有 n 个元素的集合,在每次对其进行划分时,都可以划分成由 m 个子集构成的子集,并且易知:1 <= m <= n;
//建立一个函数 F(n, m) 表示将 n 个元素的集合划分成由 m 个子集构成的集合的方法个数:
//考虑以下几种情况:
//1. 当 m == 1,则 F(n, m) = 1;
//2. 当 n == m,则 F(n, m) = 1;
//3. 若非以上两种,则 f(n, m) 可以由下面两种情况构成:
// a.向 n - 1 个元素划分成的 m 个集合里面添加一个新的元素,则有 m * F(n - 1, m) 种方法;
// 比如:1234 先将3个元素(这里 n - 1 为 3)123 划分成两个(设 m = 2)子集构成的集合{{12}{3}},然后将 4 分别加到这俩子集里:{{124}{3}} 或 {{12}{34}},也就是说每种情况都要乘上 m 种方法
// b.向 n - 1 个元素划分成的 m - 1 个集合里添加一个由一个元素形成的独立的集合,则有 F(n - 1, m - 1) 种方法。
// 比如:1234 先将3个元素 123 成 1 个(m - 1 = 1)子集构成的集合{{123}},然后将{4}这个独立子集加进去:{{123}{4}},即只有一种方法,没有乘数
//综上:F(n,m) = F(n-1,m-1) + m * F(n-1,m)
**

★C++ 代码如下 (Visual Studio 2017):

#include "stdafx.h"

#include<iostream>  
#include<cstdio>  
#include<stdio.h>
using namespace std;

int F(int n, int m)		//记录当前元素个数时,一共有多少种划分方法的函数
{
	if (m == 1 || n == m)
		return 1;
	else
		return F(n - 1, m - 1) + F(n - 1, m) * m;
}

void main()
{
	int n;
	while (!0)
	{
		cout << "Please input the total number of the elements(bigger than zero): ";
		if (scanf_s("%d", &n) >= 1)
		{
			int sum = 0;	//定义一个记录总数的变量 sum
			for (int i = 1;i <= n;i++)
			{
				sum += F(n, i);
			}
			cout << "The result is: " << sum << endl;
			cout << "_______________________________________________________________" << endl;
		}
	}
	system("pause");
}

这里写图片描述

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值