递归例题4.5集合的划分

【题目描述】

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

1.Si≠∅

2.Si∩Sj=∅           (1≤i,j≤k,i≠j)

3.S1∪S2∪S3∪…∪Sk=S

则称S1,S2,……,Sk是集合S的一个划分。它相当于把S集合中的n个元素a1,a2,……,an 放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空。请你确定n个元素a1,a2,……,an 放入kk个无标号盒子中去的划分数S(n,k)。

【输入】

给出n和k。

【输出】

n个元素a1,a2,……,an放入k个无标号盒子中去的划分数S(n,k)。

【输入样例】

10 6

【输出样例】

22827

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
long long s(int n,int k)
{
if((k==0)||(n<k)) return 0;//如果子集合的数目为零,说明已经分完了,不会再有新情况,所以为0;而数的数目比子集合还少,这种情况是不可能的,因为会有空子集
if((k==n)||(k==1)) return 1;//如果数的数目刚好等于子集合的数目,刚好一个数一个子集合,所以只有一种情况;而如果只有一个子集合,那么只能将所有的数放到那一个里去,也只有一种情况
return s(n-1,k-1)+k*s(n-1,k);//不然的话,就要分类讨论:比如说,拿出an,如果把它放进其中一个子集合,那么剩下的数有n-1个,剩下的子集合有k-1个,就要return  s(n-1,k-1)    而如果不放进子集合,那么剩下s(n-1,k)但是它最终还是要放进去,此时其他数已经放好,将它放进去有k个选择,所以要乘以k
}
int main()
{
int n,k;
cin>>n>>k;
cout<<s(n,k);
return 0;
}

做题不只是为了巩固知识点,也要开动脑筋思考。拿这个题来说,就算你递归学得再好,不去动脑思考这个题的整体思路,你是不会找到规律并做出这个题的。所以拿过一个题应该先找思路,再去动手打代码。

原文地址:https://www.cnblogs.com/57xmz/p/12339639.html

时间: 2024-10-10 23:38:40

递归例题4.5集合的划分的相关文章

函数+递归例题

日期时间函数(需要用变量调用):var b = new Date(); //获取当前时间b.getTime() //获取时间戳b.getFullYear() //获取年份b.getMonth()+1; //获取月份b.getDate() //获取天b.getHours() //获取小时b.getMinutes() //获取分钟b.getSeconds() //获取秒数b.getDay() //获取星期几b.getMilliseconds() //获取毫秒 数学函数(用Math来调用):abs(x

16 Python 递归例题

递归 1.什么是递归 recursion 递归 - 递归的定义--在一个函数里再调用这个函数本身 在一个函数里再调用这个函数本身,这种魔性的使用函数的方式就叫做递归. 递归的最大深度--997 一个函数在内部调用自己 递归的层数在python里是有限制的 997/998层 2.层数可以修改 sys模块 1 import sys #python限制在997/998 2 sys.setrecursionlimit(10000000) #可以修改 3 COUNT = 0 4 def func(): #

递归例题

公园有200个桃子,猴子每天吃掉10个,挑出2个坏的扔掉,问六天后剩余桃子数量 使用循环做的 var taozishuliang = 200; for( var i=0;i<6;i++) { taozishuliang=taozishuliang-12; } alert(taozishuliang); var sl=1 for(var i=0;i<6;i++) { sl=(sl+1)*2 } alert(sl); 公园里有一堆桃子,猴子每天吃掉一半,扔掉一个坏的,第六天发现还剩1个桃子,问原来

C# Arraylist + struct 综合练习 枚举ENUE 递归

枚举类型 一组常量的组合, 在不制定任何索引的情况下,默认第一个字段从0开始,之后的依次+1 在指定了某个索引的情况下,之后的依次+1 若之前定义的某字段的索引指向了之后的某个默认字段,那么他俩完全相同 不需要初始化 Console.WriteLine(meiju.five); //常量字段 Console.WriteLine((int)meiju.five); //字段代表的值 Console.WriteLine(meiju.one); //常量字段 Console.WriteLine((in

DP&amp;图论 DAY 4 下午图论

DP&图论  DAY 4  下午 后天考试不考二分图,双联通 考拓扑排序 图论 图的基本模型 边: 有向边构成有向图 无向边构成无向图 权值: 1.无权 2.点权 3.边权 4.负权(dij不可以跑) 环: 1. 2.重边 3.有向无环图DAG 路径: 1.简单路径:不经过重复的点  1-->2-->3 不简单路径:经过重复点  1-->2-->3-->1-->4 2.连通,具有传递性 图: 1.树:n个点,n-1条边的无环连通图 2.完全图:一个无向图,图中任

【递归与递推】集合的划分

[递归与递推]集合的划分 题目描述 设s是一个具有n个元素的集合,s={a1,a2,……,an},现将s划分成k个满足下列条件的子集合s1,s2,……,sk,且满足:(1)si≠∅(2)si∩sj=∅(3)s1∪s2∪s3∪...∪sk=s则称s1,s2,...,sk是集合s的一个划分.它相当于把s集合中的n个元素a1,a2,...,an放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空.请你确定n个元素a1,a2,...,an放入k个无标号盒子中去的划分数s(n,k). 输入

例题:用函数递归求数字n 的阶乘

class Program { // 要理解递归,先要理解递归. (这只是一句玩笑话 ) // 递归,顾名思义就是递来归去,如此反复,直到不符合某个条件. 而函数递归意思也就是函数调用函数自己. 下面用代码来示例: public int jiecheng(int n) { // 用这个函数实现阶乘 , n表示阶乘的次数 if (n <= 1) return 1; else n= n *jiecheng (n - 1); return n; } static void Main(string[]

Java中方法递归与File例题

1.有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?(不死神兔)(1)数组方式 package 递归.作业; public class TuziArray { public static void main(String[] args) { //定义数组 int arr[] = new int[100]; int m=20; arr[1] = 1;//前两个月兔子数量为1只 arr[2] = 1; arr[3

ybt1207 最大公约数问题 递归经典例题

ybt1207 最大公约数问题 递归典例 (选它只是因为太典型,不是因为懒得做难题故意放水) [题目描述] 给定两个正整数,求它们的最大公约数. [输入] 输入一行,包含两个正整数(<1,000,000,000). [输出] 输出一个正整数,即这两个正整数的最大公约数. [输入样例] 6 9 [输出样例] 3 [题解] 求最大公约数明明可以两个数同时试除所有小于等于它们的算术平方根的质数,然后把整除的数累乘,得到结果,但是这种算法不光写起来很麻烦,而且的复杂度是: \[ O(\sqrt{n})