Ka的递归编程练习 Part3|集合划分啦

 1 #include<stdio.h>
 2 int ss(int n,int k)
 3 {
 4     if(n==k||k==1) return 1;
 5     return ss(n-1,k-1)+k*ss(n-1,k);
 6 }
 7 int main()
 8 {
 9     int s,n,k;
10     scanf("%d%d",&n,&k);
11     n>=k?s=ss(n,k):s=-1;
12     printf("%d",s);
13     return 0;
14 }

集合的划分就是把一个集合的数拆成多个集合的组成,其中n为元素个数,k为集合数

具体的规则是

1、Sn∉∅;

2、Si∩Sj∈∅ (1≤i,j≤k   i≠j);

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

样例输入 2 4

样例输出 7

分析:

返回条件的话,如果k=1,只能划分一个

如果k=n,每个放一个,也只有一种情况。

对于每组n、k:

第一种情况:先把一个元素a提取出来,剩下的n-1个元素进行集合划分,再把元素a放入一个集合中,然后因为这个元素a一共有k种放法,所以总共的分法是k*s(n-1,k)

第二种情况:把元素a单独放入一个集合,剩下的进行集合划分,所以分法师s(n-1,k-1)

以上~

时间: 2024-10-28 15:19:47

Ka的递归编程练习 Part3|集合划分啦的相关文章

Ka的递归编程练习 Part4|Hanoi汉诺塔,双色汉诺塔的也有

1 #include <stdio.h> 2 void hanoi(int s,char a,char b,char c) //a是出发盘,b是中途盘,c是结束盘 3 { 4 if(s==0) return; 5 hanoi(s-1,a,c,b); //把最底下的从a借助c移动到b 6 printf("s from %c move to %c\n",a,c); 7 hanoi(s-1,b,a,c); //把刚才弄到b的借助a叠到c上 8 } 9 int main() 10

Ka的递归编程练习 Part8|回溯之二 排列组合

1 #include <stdio.h> 2 int resl[1000]={0},used[1000]={0}; 3 int n,r; 4 int tot=0; 5 void output() 6 { 7 tot++; 8 printf("<%d>:",tot); 9 int i; 10 for(i=1;i<=r;i++) 11 printf("%d ",resl[i]); 12 printf("\n"); 13

Ka的递归编程练习 Part7|素数环!

1 #include <stdio.h> 2 #include <math.h> 3 #define MAX 12 4 int used[21]={0},resl[21]={0},zs[50]={0};//used=已使用 resl=结果 zs=质数 5 int total=0; 6 void output() 7 { 8 total++; 9 printf("<%d>:",total); 10 int i; 11 for(i=1;i<=MAX

Ka的回溯编程练习 Part3|马的遍历

1 #include <stdio.h> 2 int board[100][3]={0},totally=0; 3 int x[4]={2,1,-1,-2},y[4]={1,2,2,1}; 4 void o(int k) //这个输出函数需要借助回溯中n的值来完成输出 5 { 6 totally++; 7 printf("%d:",totally); 8 int r; 9 for(r=1;r<=k-1;r++) 10 printf("|%d,%d|->

Ka的递归编程练习 Part6|简单背包问题,拒绝动规从我做起

1 #include <stdio.h> 2 #define M 10 3 int w[M]={1,3,5,7,9,11,13,15,17,19}; 4 int backpack(int n,int s) //n代表容量,s代表物品个数 5 { 6 if(n==0) return 1; //如果刚好装完,此支线满足条件,返回1 7 else if(n<0||s<=0) return 0; //此条支线出现了装一个重量超过限额或全部用完也未装满,返回0 8 else if(backp

使用模板元编程操作类型集合(C++11下的TypeList)

Wrote by mutouyun. (http://darkc.at/cxx-type-list/) 群里有个朋友要实现这么一个功能:如何在编译期把一个函数类型的参数减少一个. 简单来说,就是实现下面这个模板: remove_func_par<2, void(int, long, short)>::type; // type = void(int, long) 根据输入的编译期整数,把函数参数表里对应的参数干掉一个. 为了实现这种功能,我们需要操作变参模板的参数包.比如像这样: // mak

递归编程之我见

Table of Contents 1 前言 2 递归简介 3 利用数学知识深入对递归的认知 3.1 "求解最大素数伴侣数量"的实现 3.2 进一步改进 3.2.1 减少测试的重复性 3.2.2 当找到最优解时提前结束 4 完整的程序代码 前言 今天做了一个题目<素数伴侣>,具体如下: 输入:偶数个正整数,如,1,2,3,4 处理过程:将偶数个正整数进行配对处理,如a: (1,2)(3,4); b: (1,3)(2,4); c: (1,4)(2,3),配对的整数进行求和,a

hlg1541集合划分【01背包】

集合划分 Time Limit: 1000 MS Memory Limit: 65535 K Total Submit: 44(17 users) Total Accepted: 22(16 users) Rating:  Special Judge: No Description 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子集合的所有数字和是相等的:{3} 和

编程拾趣--集合子集问题

问题 给出一个数组,比如 {1,2,3,4},请求出数组的所有子集(1)?给出一个存在重复元素的数组,比如 {1,2,2,3,4},请求出数组的所有子集(2)?请求出所有子集并且不允许出现重复子集(3)? 准备方法 /// <summary> /// 列表深拷贝 /// </summary> public static List<T> Clone<T>(this List<T> source) { List<T> newList =