「仕上げ作業」をできるだけ早く


20

バックグラウンド

ちょっとした退屈な仕事があると想像してください。毎朝、その日に作業すべきタスクのコレクションが提供されます。各タスクには一定の期間があり、一度開始すると、一度に完了する必要があります。上司はアイドリングを許容しないので、家に帰る前にまだ完了できるタスクがある場合は、そのうちの1つで作業する必要があります(どちらを選択するかは選択できます)。逆に、残りのすべてのタスクで残業が必要な場合は、早めに帰宅してください!したがって、あなたの目標は、賢明なスケジューリングにより、勤務時間を最小限に抑えることです。

楽しい事実:これは、怠zyな官僚のスケジューリング問題の 1つのバリアントであり、NPハード(ソース)です。

入力

2つの入力があります:就業日の「時間単位」の数(正の整数L)、およびタスクのコレクション(Tタスクの継続時間を表す、空でない正の整数の配列)。それらは、任意の順序で、合理的な形式で服用できます。配列にTは、期間がを超えるタスクが含まれることがありますが、期間が最大Lで少なくとも1つのタスクが含まれることが保証されますL

出力

有効なスケジュールは、タスクのサブセットであるS ⊆ Tようにsum(S) ≤ Lしていない、そしてすべてのタスクS(カウント多重度)、厳密以上の持続時間を有しますL - sum(S)。あなたの出力は、有効なスケジュールの可能な限り最小の合計となります。言い換えれば、今日作業しなければならない時間単位の最小数を出力しなければなりません。

入力を検討する

L = 9
T = [3,4,4,4,2,5]

1日をスケジュールする1つの方法は、[4,4]2つのタスクを8つの時間単位で完了し、1つの単位を残すことです。1ユニットのタスクは利用できないため、家に帰ることができます。ただし、スケジュール[2,5]はさらに優れています。7時間単位で作業すると、残りのタスクはすべて3時間単位以上かかります。[2,4]6時間単位で作業した後でも、3単位タスクを完了するのに十分な時間があるため、スケジュールは無効です。7ユニットが最適であることが判明したため、正しい出力は7です。

ルールとスコアリング

完全なプログラムまたは関数のいずれかを作成できます。最小のバイトカウントが優先され、標準の抜け穴は許可されません。時間制限はないため、ブルートフォースは完全に受け入れられます。

テストケース

これらは形式で与えられますL T -> output

 1 [1,2] -> 1
 6 [4,1] -> 5
 7 [7,7,9] -> 7
 9 [3,4,4,4,2,5] -> 7
20 [6,2,3,12,7,31] -> 17
42 [7,7,7,7,8,8,8] -> 36
42 [7,7,7,7,7,8,8,8] -> 35
42 [7,7,7,7,7,7,8,8,8] -> 36
16 [1,2,3,4,5,6,7,8,9,10] -> 13
37 [15,27,4,1,19,16,20,26,29,18] -> 23
22 [24,20,8,8,29,16,5,5,16,18,4,9] -> 18
80 [10,22,11,2,28,20,27,6,24,9,10,6,27,2,15,29,27] -> 71
59 [26,28,5,4,7,23,5,1,9,3,7,15,4,23,7,19,16,25,26] -> 52

回答:


3

ゼリー、20バイト

³œ-;⁴Ṃ;¹S>⁴
ŒPÇÐfS€Ṃ

オンラインでお試しください!

TIOは、わずかでも、60秒の制限時間内に最後のテストケースを完了するのに十分な速さです。

バックグラウンド

アルゴリズムは単純で非効率的です:

  1. Tのすべてのサブセットを生成し、多重度をカウントします。

  2. サブセットをフィルタリングし、次の基準のいずれかを満たすサブセットSのみを保持します。

    • Sは、異なるT、の要素の和Sと最小の要素ではないSは、より大きいL

    • STは同一です。

    フィルター処理されたT(これをT 'と呼びましょう)には、十分な作業(または時間外労働)を行うタスクのすべてのリストが含まれています。

  3. すべてのSにおけるT」、最低の合計で1を選択します。

使い方

ŒPÇÐfS€Ṃ     Main link. Left input: T (list). Right input: L (integer).

ŒP           Powerset; generate all subsets of T.
   Ðf        Filter them...
  Ç            applying the helper link.
     S€      Compute the sum of each kept subset.
       Ṃ     Take the minimum.

³œ-;⁴Ṃ;¹S>⁴  Helper link. Input: A (subset of T)

³œ-          Multiset subtraction; remove the elements of A from T, counting
             multiplicities.
   ;⁴        Append L to the resulting list.
     Ṃ       Take the minimum.
             If S == T, the difference was empty and the minimum is L.
      ;¹     Prepend the minimum to A.
        S    Compute the sum.
         >⁴  Compare it with L.
             If S == T, the comparison will return 1.


1

ルビー、124バイト

->(m,s){
f=proc{|l,t|t.reject!{|x|x>l}
(0...(t.size)).map{|x|
f.call(l-t[x],t[0,x]+t[(x+1)..-1])
}.max||l
}
m-f.call(m,s)
}

これはブルートフォースソリューションです。


1

MATL、36バイト

iTFinZ^!"2G@2#)sXKt1G>~wb+lG>A*?KhX<

オンラインでお試しください!

i           % input number L
TF          % array [true, false]
in          % input array T. Get its length
Z^!         % Cartesian power and transpose. Each column is a selection from T
"           % for each selection
  2G@2#)    %   take non-selected and then selected tasks
  sXK       %   sum of selected tasks. Copy to clipboard K
  t1G>~     %   duplicate. Is sum of selected tasks <= L?
  wb        %   swap, rotate
  +         %   sum of selected tasks plus each non-selected task
  lG>A      %   are all of those numbers greater than L?
  *         %   are both conditions met?
  ?         %   if so
    Kh      %     paste current minimum (or initially L), append new value
    X<      %     compute new minimum
            %   end if implicitly
            % end for each implicitly
            % display stack implicitly
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.