Recursion 在ocaml中查找给定数量足球比赛的所有排列

Recursion 在ocaml中查找给定数量足球比赛的所有排列,recursion,ocaml,permutation,Recursion,Ocaml,Permutation,我必须编写函数系列:int->int->result list,第一个int表示游戏数量,第二个int表示积分 我已经考虑过通过创建所有排列和过滤列表的经验解决方案,但我认为这将是ocaml非常脏的解决方案,有很多行代码。我找不到另一种方法来解决这个问题 给出了以下类型 type result=Win(*3分*) |绘制(*1点*) |损失(*0分*) 所以如果我打电话 series 3 4 解决办法应该是: [[Win ;Draw ;Loss]; [Win ;Loss ;Draw]; [D

我必须编写函数系列:int->int->result list,第一个int表示游戏数量,第二个int表示积分

我已经考虑过通过创建所有排列和过滤列表的经验解决方案,但我认为这将是ocaml非常脏的解决方案,有很多行代码。我找不到另一种方法来解决这个问题

给出了以下类型

type result=Win(*3分*)
|绘制(*1点*)
|损失(*0分*)
所以如果我打电话

series 3 4
解决办法应该是:

[[Win ;Draw ;Loss]; [Win ;Loss ;Draw]; [Draw ;Win ;Loss];
[Draw ;Loss ;Win]; [Loss ;Win ;Draw]; [Loss ;Draw ;Win]]

也许有人可以给我一个提示或代码示例如何开始。

< P>考虑表单“代码>系列N(N/2)< /C> >的调用,并考虑所有游戏都是<代码>绘制<代码>或<代码>丢失< /代码>的情况。在这些限制条件下,答案的数量与
2^n/sqrt(n)
成正比。(网上的家伙们从斯特林近似得到了这个。)

这不包括任何一个系列赛,任何人都会赢得一场比赛。因此,实际的结果列表通常比这要长

我的结论是,可能的答案数量是巨大的,因此,你的实际案例将是小的

如果您的实际案例很小,那么使用暴力方法可能没有问题

与您的说法相反,暴力代码通常非常简短且易于理解


您可以轻松地编写一个函数,列出所有可能的长度序列
n
,这些序列取自
Win、Lose、Draw
。然后,您可以过滤它们以获得正确的总和。由于上述接近指数的行为,渐进地说,这可能只比最快的算法差一点。

简单的递归解决方案如下:

  • 如果有0场比赛要玩,0分要赚,那么只有一个(空)解决方案
  • 如果要玩0场比赛,要赢取1分或更多分,就没有解决方案
  • 否则,
    p
    积分必须在
    g
    游戏中获得:任何
    p
    积分在
    g-1
    游戏中的解决方案都可以通过在前面添加一个
    Loss
    扩展为一个解决方案。如果
    p>=1
    ,您可以类似地为
    g-1
    游戏中
    p-1
    的任何解决方案添加
    Draw
    ,如果
    p>=3
    ,也可能从
    赢开始