Mümkün olduğunca erken “işi bitir”


20

Arka fon

Bir an için akıl almaz derecede sıkıcı bir işin olduğunu hayal et. Her sabah, o gün çalışmanız gereken bir dizi görev verilir. Her görevin belirli bir süresi vardır ve başlatıldıktan sonra, bir seferde tamamlanmalıdır. Patronunuz rölantide tolere etmeyecektir, bu yüzden eve gitmeden önce hala tamamlayabileceğiniz görevler varsa, bunlardan biri üzerinde çalışmalısınız (hangisini seçeceğinizi seçebilirsiniz). Tersine, kalan tüm görevler fazla mesai yapmanızı gerektiriyorsa, eve erken dönebilirsiniz! Böylece amacınız akıllı zamanlama ile iş gününüzün uzunluğunu en aza indirmek.

Eğlenceli gerçek: Bu tembel bürokrat çizelgeleme probleminin bir varyantı ve NP zor ( kaynak ).

Giriş

İki girişiniz vardır: iş gününüzdeki "zaman birimleri" sayısı (pozitif bir tam sayı L) ve görevlerin toplanması ( Tgörev sürelerini temsil eden boş olmayan pozitif tamsayılar dizisi ). Herhangi bir sırada ve makul bir formatta alınabilirler. Dizi T, süresi daha uzun olan görevler içerebilir L, ancak en fazla süresi olan en az bir görev içermesi garanti edilir L.

Çıktı

Bir geçerli zamanlama görevleri bir alt kümesidir S ⊆ Töyle ki sum(S) ≤ L, değil her görev S(sayım çokluklar) kesinlikle daha fazla süreye sahip L - sum(S). Çıktınız geçerli bir programın mümkün olan en küçük toplamı olacaktır. Başka bir deyişle, bugün çalışmanız gereken minimum zaman birimi sayısını çıkarmalısınız.

Misal

Girdileri düşünün

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

Gününüzü planlamanın bir yolu şudur [4,4]: 8 zaman biriminde iki görevi bitirirsiniz ve 1 birim kalır. 1 birim görev olmadığından eve gidebilirsiniz. Ancak, zamanlama [2,5]daha da iyidir: 7 zaman birimi için çalışırsınız ve kalan tüm görevler 3 veya daha fazla zaman birimi alır. Zamanlama [2,4]geçerli değildir, çünkü 6 zaman birimi için çalıştıktan sonra, 3 birim görevini bitirmek için yeterli zamanınız olacaktır. 7 birim en uygun olduğu ortaya çıktı, bu yüzden doğru çıktı 7.

Kurallar ve puanlama

Tam bir program veya bir işlev yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez. Zaman bağlı değildir, bu nedenle kaba zorlama mükemmel kabul edilebilir.

Test senaryoları

Bunlar formatta verilmiştir 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

Yanıtlar:


3

Jöle, 20 bayt

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

Çevrimiçi deneyin!

TIO, zar zor bile olsa son test senaryolarını 60 saniyelik süre içinde bitirmek için yeterince hızlıdır.

Arka fon

Algoritma hem basit hem de verimsizdir:

  1. Çoklukları sayarak T'nin tüm alt kümelerini üretiyoruz .

  2. Alt kümeleri filtreleyerek yalnızca aşağıdaki ölçütlerden birini karşılayan alt kümeleri S saklarız:

    • S farklıdır T ve elemanlarının toplamı S ve minimal elemanı olup içinde S daha büyüktür L .

    • S ve T aynıdır.

    Filtrelenmiş T (buna T ' diyelim ) artık yeterli iş (hatta fazla mesai) yapan tüm görev listelerini içeriyor.

  3. T ' deki tüm S'ler arasından en düşük toplamı seçin.

Nasıl çalışır

Œ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

Pyth, 26 25 bayt

JEhSsMf&gJsT>hS.-QT-JsTyQ

Çevrimiçi deneyin. Test odası.

Son iki test vakasını çalıştıramadım (çevrimiçi zaman aşımına uğradı, sanırım), ancak diğerleri çalışıyor. Bu sadece temel bir kaba kuvvet çözümüdür.


1

Ruby, 124 bayt

->(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)
}

Bu kaba kuvvetli bir çözümdür.


1

MATL , 36 bayt

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

Çevrimiçi deneyin!

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.