IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Bailian3253 集合的划分【递归】 -> 正文阅读

[C++知识库]Bailian3253 集合的划分【递归】

3253:集合的划分

总时间限制: 1000ms 内存限制: 65536kB
描述
把一个集A(本题中的集合均不含重复元素)分成若干个非空子集,使得A中每个元素属于且仅属于一个子集,那么这些子集构成的集合称为A的一个划分。比如A={1,2,3},那么{ {1},{2 ,3} }以及{ {1},{2},{3} } 都是A的划分。现在给定一个整数n,我们希望知道包含n个元素的集合有多少不同的划分。当n=3的时候,仍然考虑集合{1,2,3},它的所有划分如下
{ {1} , {2} , {3} }
{ {1 , 2} , {3} }
{ {1 , 3} , {2} }
{ {1} , {2 , 3} }
{ {1 , 2 , 3} }
只有5种,但随n的增加,划分方法的个数会以指数速度增加。比如n=4的时候,就有15种方法,考虑集合{1,2,3,4},划分方式如下
{ {1},{2},{3},{4}}
{{1},{2},{3,4}}
{{1,2},{3},{4}}
{{1,3},{2},{4}}
{{1,4},{2},{3}}
{{1},{2,3},{4}}
{{1},{3},{2,4}}
{{1,2},{3,4}}
{{1,3},{2,4}}
{{1,4},{2,3}}
{{1},{2,3,4}}
{{2},{1,3,4}}
{{3},{1,2,4}}
{{4},{1,2,3}}
{{1,2,3,4}}
当n>15的时候,划分方法数将超过32位整数所能表示的范围,我们希望你的程序能计算出n<=15的时候,包含n个元素的集合的划分方法的个数
输入
一个整数n(0<=n<=15,n=0的时候认为有一种划分方法)
输出
包含n个不同元素的集合的划分方法的个数
样例输入
3
15
样例输出
5
1382958545
提示
递归公式,
设n个元素的集合可以划分为F(n,m)个不同的由m个非空子集组成的集合。
F(n,m) = 1, where n=0, n=m, n=1, or m=1
F(n,m) = 0, where n<m
否则
F(n,m)=F(n-1,m-1)+m*F(n-1,m)

例如:
考虑3个元素的集合,可划分为
① 1个子集的集合:{{1,2,3}}
② 2个子集的集合:{{1,2},{3}},{{1,3},{2}},{{2,3},{1}}
③ 3个子集的集合:{{1},{2},{3}}
∴F(3,1)=1;F(3,2)=3;F(3,3)=1;

如果要求F(4,2)该怎么办呢?

A.往①里添一个元素{4},得到{{1,2,3},{4}}

B.往②里的任意一个子集添一个4,得到
{{1,2,4},{3}},{{1,2},{3,4}},
{{1,3,4},{2}},{{1,3},{2,4}},
{{2,3,4},{1}},{{2,3},{1,4}}

∴F(4,2)=F(3,1)+2F(3,2)=1+23=7
来源
cs10107 C++ Final Exam

问题链接Bailian3253 集合的划分
问题简述:(略)
问题分析:递归组合问题,用递归函数来解决。如果需要加速,可以使用记忆化递归来实现。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* Bailian3253 集合的划分 */

#include <stdio.h>

long long fun(int n,int m)
{
    if (n < m) return 0;
    else if (n == 0 || n == m || n == 1 || m == 1) return 1;
    else return fun(n - 1, m - 1) + m * fun(n - 1, m);
}

int main()
{
    int n;
    while (scanf("%d", &n)!=EOF) {
        long long ans = 0;
        if (n == 0)
            ans = 1;
        else
            for (int i = 1; i <= n; i++)
                ans += fun(n, i);

        printf("%lld\n",ans);
    }
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:11:57  更:2022-04-24 09:12:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:23:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码