重箱堆叠


27

您有一堆沉重的箱子,并且希望将它们堆叠在尽可能少的堆叠中。问题是您不能在一个盒子中堆放更多的盒子,因此不能容纳更多的盒子,因此较重的盒子必须放在盒子的底部。

挑战

输入:整箱重量列表,以千克为单位。

输出:描述盒子堆栈的列表列表。这必须使用最少数量的堆栈作为输入。要成为有效的堆栈,堆栈中每个盒子的重量必须大于或等于其上方所有盒子的重量之和。

有效堆栈的示例

(按从下到上的顺序)

  • [3]
  • [1,1]
  • [3,2,1]
  • [4,2,1,1]
  • [27、17、6、3、1]
  • [33,32,1]
  • [999,888,99,11,1]

无效堆栈的示例

(按从下到上的顺序)

  • [1,2]
  • [3,3,3]
  • [5、5、1]
  • [999、888、777]
  • [4、3、2]
  • [4321、3000、1234、321]

示例测试用例

1个

IN: [1, 2, 3, 4, 5, 6, 9, 12]
OUT: [[12, 6, 3, 2, 1], [9, 5, 4]]

2

IN: [87, 432, 9999, 1234, 3030]
OUT: [[9999, 3030, 1234, 432, 87]]

3

IN: [1, 5, 3, 1, 4, 2, 1, 6, 1, 7, 2, 3]
OUT: [[6, 3, 2, 1], [7, 4, 2, 1], [5, 3, 1, 1]]

4

IN: [8, 5, 8, 8, 1, 2]
OUT: [[8, 8], [8, 5, 2, 1]]

规则与假设

  • 适用标准I / O规则和禁止的漏洞
  • 使用任何方便的I / O格式
    • 只要您保持一致,就可以从上到下或从下到上描述堆栈。
    • 堆栈的顺序(而不是这些堆栈中的框)无关紧要。
    • 您也可以将输入框作为预排序列表。顺序对于输入不是特别重要,只要排序本身不能解决一般问题即可。
  • 如果有多个最佳配置的堆栈,则可以输出其中任何一个
  • 您可以假设至少有一个盒子,所有盒子的重量至少为1公斤
  • 您必须支撑的重量至少为9,999 kg。
  • 最少必须支持总共9,999个盒子。
  • 重量相同的盒子是无法区分的,因此无需注释在哪里使用了哪个盒子。

打高尔夫球快乐!祝好运!


2
我们可以按重量排序吗?(上升或下降)
Arnauld

4
“您最多必须支持多达9,999个盒子。” 在这里如何解释“支持”?这是否仅表示该程序应该能够接受这种大小的输入,还是意味着该程序实际上应在合理的时间内提供答案?如果是后者,则应该提供更大的测试用例。
乔尔

1
建议的测试用例:[8, 8, 8, 5, 1]->[[8, 8], [8, 5, 1]]
Hiatsu

3
甚至更好:[8, 5, 8, 8, 1, 2]->[[8, 8], [8, 5, 2, 1]]
Hiatsu

2
@Arnauld,因为否则会给答案添加无趣的排序代码,我要说,您可以按排序的顺序输入输入。
Beefster

Answers:


5

果冻,19字节

Œ!ŒṖ€ẎṖÄ>ḊƲ€¬ȦƊƇLÞḢ

在线尝试!

显然-3多亏了尼克·肯尼迪Nick Kennedy) ...

从上到下。

说明:

Œ!ŒṖ€ẎṖÄ>ḊƲ€¬ȦƊƇLÞḢ  Arguments: S (e.g. [1, 2, 3, 4, 5])
Œ!                   Permutations (e.g. [..., [4, 1, 5, 2, 3], ...])
    €                Map link over left argument (e.g. [..., [..., [[4, 1], [5], [2, 3]], ...], ...])
  ŒṖ                  Partitions (e.g. [..., [[4, 1], [5], [2, 3]], ...])
     Ẏ               Concatenate elements (e.g. [..., ..., [[4, 1], [5], [2, 3]], ..., ...])
               Ƈ     Filter by link (e.g. [..., [[1, 3], [2], [4], [5]], ...])
              Ɗ       Create >=3-link monadic chain (e.g. [[1], [], [0]])
           €           Map link over left argument (e.g. [[1], [], [0]])
          Ʋ             Create >=4-link monadic chain (e.g. [1])
      Ṗ                  Remove last element (e.g. [4])
       Ä                 Cumulative sum (e.g. [4])
         Ḋ               [Get original argument] Remove first element (e.g. [1])
        >                Greater than (vectorizes) (e.g. [1])
            ¬          Logical NOT (vectorizes) (e.g. [[0], [], [1]])
             Ȧ         Check if non-empty and not containing zeroes after flattening (e.g. 0)
                 Þ   Sort by link (e.g. [[[1, 2, 3], [4, 5]], ..., [[5], [4], [3], [2], [1]]])
                L     Length (e.g. 4)
                  Ḣ  Pop first element (e.g. [[1, 2, 3], [4, 5]])

有机会使用不太精巧的版本并提供解释吗?我从那些中学到了很多。
John Keates

1
@JohnKeates添加了一个。
暴民埃里克

5

JavaScript(Node.js), 139122116 字节

期望输入以升序排序。

f=(A,s=[],[n,...a]=A,r)=>n?s.some((b,i,[...c])=>n<eval(b.join`+`)?0:f(A,c,a,c[i]=[n,...b]))?S:r?0:f(A,[...s,[]]):S=s

在线尝试!

已评论

f = (                        // f is a recursive function taking:
  A,                         //   A[] = input array
  s = [],                    //   s[] = list of stacks, initially empty
  [n,                        //   n   = next weight to process
      ...a] = A,             //   a[] = array of remaining weights
  r                          //   r   = recursion flag
) =>                         //
  n ?                        // if n is defined:
    s.some((b, i,            //   for each stack b[] at position i in s[],
                  [...c]) => //   using c[] as a copy of s[]:
      n < eval(b.join`+`) ?  //     if n is not heavy enough to support all values in b[]:
        0                    //       abort
      :                      //     else:
        f(                   //       do a recursive call:
          A, c, a,           //         using A[], c[] and a[]
          c[i] = [n, ...b]   //         with n prepended to c[i]
        )                    //       end of recursive call
    ) ?                      //   end of some(); if successful:
      S                      //     return S[]
    :                        //   else:
      r ?                    //     if this is a recursive call:
        0                    //       do nothing
      :                      //     else:
        f(A, [...s, []])     //       try again with an additional stack
  :                          // else:
    S = s                    //   success: save the solution in S[]

2

Python 3.8(预发布),178字节

f=lambda b,s=[[]]:(a for i in range(len(s))if b[0]>=sum(s[i])for a in f(b[1:],s[:i]+[[b[0]]+s[i]]+s[i+1:]+[[]]))if b else[s]
g=lambda a:(c:=sorted(f(a),key=len)[0])[:c.index([])]

在线尝试!

现在适用于所有可能的输入。(它在TIO上超过十个左右的框时超时,但是它计算出正确的答案)


2
list(reversed(sorted(a)))可以写sorted(a)[::-1]为打高尔夫球的目的。
乔尔

您可能会想我现在就知道了,尤其是因为我做了很多其他索引工作。谢谢。
Hiatsu

顺便提一句,如果不打高尔夫球,最好改写sorted(a, reverse=True)
乔尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.