【发布时间】:2015-10-27 16:07:38
【问题描述】:
是否有任何有效的方法可以将集合{1, ... , 2*n} 的所有部分列成n 对?
最简单的想法是列出所有排列,然后排列(a1, a2, ... , a8) 表示除法{{a1,a2}, ... , {a7,a8}}。在这种情况下,每个分区都有2^n * n! 排列。这是O((2n)!)。
我能找到更有效的方法吗?
【问题讨论】:
-
枚举对很容易。如果您允许在“提取”一对之后按顺序将索引重新标记为最低可用值的约定,您将在 kC2 项之间获得一个平面(而不是树)系列选择,其中 k in (2*n down to 2 步骤 2)。然后,您可以做出选择,从 2*n 下降到 2,并根据这些选择“读取”原始索引备份链。权衡是 O(n) 而不是 O(1) 选择时间。稍后我会整理一些代码,也许是为了一个真正的“答案”,如果没有人能打败我......
-
谢谢你的回答,但很遗憾我不明白你的算法。如果你写一些伪代码,我将不胜感激。
-
顺序重要吗?如果您列出所有排列,您会得到很多与
{{y,x}...}分开列出的{{x,y}...},这就是您想要的吗? -
pair 内部的顺序无关紧要,pair 的顺序也不重要。我想找到某种方法将 {1,...,2*n} 的所有划分列出为二元素子集。例如 1,2 - 3,4 - 5,6 - 7,8 是一个分区 2,1 - 3,4 - 5,6 - 7,8 是同一个分区 3,4 - 1,2 - 5,6 - 7,8也是同样的划分。集合 {1,...2*n} 的所有划分为“对”的数量为 (2n-1)*(2n-3)*(2n-5)* ... *5*3*1我想以某种有效的方式列出所有这些。
标签: algorithm discrete-mathematics