我有关于组合数学问题。 不幸的是,我不能抽象地,所以我试图解释它作为一个故事,描述它。 :)
问题:
- 有在校园100名儿童。
- 它们都具有独特的高度,假设值是100-199cm。
- 你想建立10组,每组1-99的儿童。
- 你怎么能建立所有的组,而儿童必须由自己的身高进行排序?
- 我需要为这些群体所有可能的解决方案,因为它不是很难找到一个星座。
短而简单:
所有的100名儿童并肩而立。 你只需要决定在哪里他们分成不同的小组发现这一切的解决方案。
实施例(的值是高度):
[120 ... 190 ... 199] ... [126 ... 137 ... 144 ... 188] 是不可能
[101] ... [104 ... 105 ... 112 ... 149] ... [169 ... 189] 是可能
我希望你能帮助我。 非常感谢你提前!
PS:这是没有的功课。 ;)通常情况下,我需要一个函数,这是否与数字。 但我无法描述这种抽象,如“门牌的K组,而所有数字进行排序”。 我以为你不会明白这种方式。 :)在PHP中的解决方案是最好的,但我会很高兴地看到其他语言的解决方案,以及。 :)
据我所知,您实际上要求分割区间[100199]到10份的方式,也就是你想找到数x [0],...,X [10]这样的:
x[0] = 100 < x[1] < x[2] < ... < x[9] < x[10] = 199
定义递归函数partition(intervalSize, pieces)
进行计数的方法来分割给定的时间间隔的数目。 您是后partition(100, 10)
下面的Java代码计算分区(对不起,不知道PHP那么好):
public class Partitions
{
static long[][] partitions = new long[100][10];
private static long partition(int intervalSize, int pieces)
{
if (partitions[intervalSize-1][pieces-1] != 0) {
return partitions[intervalSize-1][pieces-1];
}
long partition = 0L;
if (pieces == 1) {
partition = 1L;
} else {
for (int i = 1; i <= intervalSize - 1; i++) {
partition += partition(intervalSize - i, pieces - 1);
}
}
partitions[intervalSize-1][pieces-1] = partition;
return partition;
}
public static void main(String[] args)
{
System.out.println(partition(100, 10));
}
}
下面的Java代码打印出实际的分区。 由于分区数量为(100,10)那么高,我出的答案(5,3):
public class Partitions2
{
private static void showPartitions(int sizeSet, int numPartitions)
{
showPartitions("", 0, sizeSet, numPartitions);
}
private static void showPartitions(String prefix, int start, int finish,
int numLeft)
{
if (numLeft == 0 && start == finish) {
System.out.println(prefix);
} else {
prefix += "|";
for (int i = start + 1; i <= finish; i++) {
prefix += i + ",";
showPartitions(prefix, i, finish, numLeft - 1);
}
}
}
public static void main(String[] args)
{
showPartitions(5, 3);
}
}
输出是:
|1,|2,|3,4,5,
|1,|2,3,|4,5,
|1,|2,3,4,|5,
|1,2,|3,|4,5,
|1,2,|3,4,|5,
|1,2,3,|4,|5,
我需要为这些群体所有可能的解决方案,因为它不是很难找到一个星座。
通常情况下,100! 方式来置换100个项目,但因为你是维持秩序,就可以大大减少你的问题的规模了。 什么你所描述的是一个整数分割问题 。 例如,假设你在分区数目5进入所有可能的整数的子集,其新增多达5个,你会得到的集{5},{4,1},{3,2},{3,1,1 ,},{2,2,1},{2,1,1,1},{1,1,1,1,1}。
整数分区的数量与整数的大小呈指数增长,但指数增长足够慢,你可以通过N = 100的所有分区枚举,因为只有他们190569292的。 这里的附加约束条件是要过滤所有的分区的整整含10项,这是很容易通过使用费雷尔图枚举集。
我可以证明由分区的数目20费雷尔图分为3桶:开始用20山口×3行格如下:
12345678901234567890
1******************
2*
3*
所以,第一个分区是{18,1,1}
现在从堆栈到下一槽的顶部移动的项目:
12345678901234567890
1*****************
2**
3*
我们的新的分区是{17,2,1}。 我们可以从一个堆栈到其它另一个项目:
12345678901234567890
1****************
2***
3*
现在我们有{16,3,1}。 你继续这样做,直到你枚举所有排列(它取决于你是否{17,1,2}是从不同的分区{17,2,1})。
从这一点来说,你应该能够想象你所需要的算法的大致轮廓 - 也就是说,如果你想从头开始编写此功能的挑战。 其他人已经写了很多的高效功能轻松解决这个问题。
文章来源: Combinatorics: Building 10 groups of 100 elements while elements remain sorted