C++ N个节点随机排列组合可以生成多少不同的树?

neeeewbee 2020-12-14 10:11:49


如图所示,N个相同的圆有共同的橙色方块祖先,一共能生成多少个不同的树,求一个算法思路,如果能把具体实现出来就跪谢了。
...全文
1195 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2020-12-27
  • 打赏
  • 举报
回复
引用 2 楼 赵4老师 的回复:
拢共分三步: 1.先设N为1,2,3,自己在纸上用铅笔,橡皮画画 2.再找规律 3.再编写规律对应的递归程序
1、把冰箱门打开 2、把大象放进去 3、把冰箱门关上。 第2步比较难。 所以咱这个问题也是第2步找规律比较难哈。
  • 打赏
  • 举报
回复
分块还要去重,只需要考虑具有不同节点数的分块,已经接近最后的胜利~
  • 打赏
  • 举报
回复
是的,确实是3种,多谢老赵帮我发现了一个算法上的BUG,计算某一层对上一层的拆分数,不能只考虑上一层的节点总数,还要考虑分块数
赵4老师 2020-12-27
  • 打赏
  • 举报
回复
这冰箱质量也忒好了!
  • 打赏
  • 举报
回复
发现规律:把老赵装进冰箱比把大象装进冰箱容易多了~
  • 打赏
  • 举报
回复
引用 41 楼 赵4老师 的回复:
参考#37
n(6)=48


没有48,肯定是其他地方多算了,要不你画出来~

赵4老师 2020-12-26
  • 打赏
  • 举报
回复
版主竟然还不把本贴加精
赵4老师 2020-12-26
  • 打赏
  • 举报
回复
参考#37 n(6)=48
  • 打赏
  • 举报
回复
终于有时间研究了一下,#33说n(6)=47应该是对的,这个问题用整数拆分方法解决是完全可行的(而且比较简单)。
老赵一直在说“拓扑问题”,但是拓扑问题不是靠拓扑两个字解决的,实际上组合数学研究的抽屉问题(整数拆分是抽屉问题的一个抽象)、染色问题、旅行路径问题都属于拓扑问题。
简单说,解决楼主的问题,n个相同节点(n不包括固定的根节点)生成树的数量,分成两个步骤:

第一步,求n个节点的排列关系,不考虑节点之间的父子关系,相当于把树的节点之间的连线去掉的形态,这种拆分叫composition,是有顺序的,1-2-3和1-3-2、3-1-2属于不同拆分,c(n)=2^(n-1),这个就不证明了,早就有人证过了。

第二步,对第一步生成的每一种节点排列形式,求每一层对上一层的拆分数,比如某种节点排列形式第一层有两个节点,第二层有三个,则求p(2, 1)、p(3, 2),第一层不需要计算,因为p(n, 1)=1。p(n, k)表示把n拆分为k个非负整数(允许0)之和的数量,不考虑顺序关系,1-2和2-1是同一种拆分。p(n, k)可以递归实现,比较简单。把每一层求得的拆分数相乘,即是该种节点排列形式下生成树的总数。

将每种节点排列形式下生成树的数量相加,就是n个节点的生成树的总数。
简单计算结果(不保证正确):
n(1) = 1
n(2) = 2
n(3) = 4
n(4) = 9
n(5) = 20
n(6) = 47
n(7) = 109
n(8) = 258
n(9) = 608
n(10) = 1443
32位有符号数只能计算到n=26
赵4老师 2020-12-26
  • 打赏
  • 举报
回复
看#37楼的图,231明明有3种。
赵4老师 2020-12-26
  • 打赏
  • 举报
回复
我是剑宗;你是气宗。 我是拓扑画派;你是排列组合解析派。 两大派决战CSDN BBS!
赵4老师 2020-12-26
  • 打赏
  • 举报
回复
引用 43 楼 早打大打打核战争 的回复:
[quote=引用 41 楼 赵4老师 的回复:]参考#37 n(6)=48
没有48,肯定是其他地方多算了,要不你画出来~ [/quote] #37
引用 43 楼 早打大打打核战争 的回复:
[quote=引用 41 楼 赵4老师 的回复:]参考#37 n(6)=48
没有48,肯定是其他地方多算了,要不你画出来~ [/quote] 我#37楼不已经画出来了吗? 你能用红圈圈出我#37楼画的图里哪种情况是你认为多余的那种,或圈出哪两个重复了,所以你认为的正确答案是47吗?
  • 打赏
  • 举报
回复
所以,n=6的总数还是47,不是48
  • 打赏
  • 举报
回复
第一层2个叶子:如果24,有3种情况,231有3种,22x有5种,21x有4种 一共15
================================================
24有3种
231有3种是错的,只有2种
222有4种
2211有2种
213有1种
2121有1种
2112有2种
一共15
#33有两处算错了,但总数还是对的
赵4老师 2020-12-22
  • 打赏
  • 举报
回复
纠正#37,22x有6种而不是5种
赵4老师 2020-12-22
  • 打赏
  • 举报
回复
引用 19 楼 赵4老师 的回复:
拓扑问题,离开拓扑似乎没办法解决。
顶自己!
赵4老师 2020-12-22
  • 打赏
  • 举报
回复
引用 33 楼 nice_cxf 的回复:
6层似乎是47?不知道对不对 第一层1个叶子:相当于5层,20个 第一层2个叶子:如果24,有3种情况,231有3种,22x有5种,21x有4种 一共15 第一层3个叶子:33 有3种,321有2种,31x有2种,一共7 第一层4个叶子:3种 第一层5个叶子:1 第一层6个叶子:1 一共1+1+3+7+15+20=47
如图,22x有5种而不是4种:
  • 打赏
  • 举报
回复
就这还要1000?这个问题就是整数拆分,允许包含0的拆分,比如第一层2个,第二层4个,那么第二层的组合数就是4的2拆分(允许包含0),共3种:
4 0
3 1
2 2
赵4老师 2020-12-22
  • 打赏
  • 举报
回复
引用 32 楼 nice_cxf 的回复:
5层是20,少了个131,规律很难找
感谢斧正:
  • 打赏
  • 举报
回复
请老赵解释一下
加载更多回复(33)

65,209

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧