“ เสร็จงาน” โดยเร็วที่สุด


20

พื้นหลัง

ลองนึกภาพสักครู่ว่าคุณมีงานที่น่าเบื่ออย่างเหลือเชื่อ ทุกเช้าคุณจะได้รับชุดของงานที่คุณควรทำงานในวันนั้น แต่ละงานมีระยะเวลาแน่นอนและเมื่อเริ่มต้นแล้วจะต้องทำให้สำเร็จในครั้งเดียว เจ้านายของคุณจะไม่ยอมเกียจคร้านดังนั้นถ้ามีงานที่คุณยังสามารถทำให้เสร็จก่อนกลับบ้านคุณจะต้องทำงานกับสิ่งใดสิ่งหนึ่ง (คุณสามารถเลือกได้) ในทางกลับกันถ้างานที่เหลืออยู่ทั้งหมดจะทำให้คุณต้องทำงานล่วงเวลาคุณจะต้องกลับบ้านก่อน! ดังนั้นเป้าหมายของคุณคือการลดระยะเวลาการทำงานของคุณให้สั้นที่สุดด้วยการกำหนดตารางเวลาที่ชาญฉลาด

ความจริงแล้วสนุก: นี่เป็นหนึ่งในตัวแปรของปัญหาการจัดตารางเวลาขี้เกียจของระบบราชการและมันเป็นปัญหาที่ยาก ( แหล่งที่มา )

อินพุต

คุณมีสองอินพุต: จำนวนของ "หน่วยเวลา" ในวันทำงานของคุณ (จำนวนเต็มบวกL) และการรวบรวมงาน (อาร์เรย์ที่ไม่ว่างของจำนวนเต็มบวกTแสดงถึงระยะเวลาของงาน) พวกเขาสามารถดำเนินการในลำดับใด ๆ และในรูปแบบที่เหมาะสม อาร์เรย์Tอาจจะมีงานที่มีระยะเวลามากกว่าแต่ก็รับประกันได้ว่าจะมีอย่างน้อยหนึ่งงานที่มีระยะเวลาที่มากที่สุดLL

เอาท์พุต

ตารางเวลาที่ถูกต้องเป็นส่วนหนึ่งของงานS ⊆ Tดังกล่าวที่sum(S) ≤ Lและงานที่ไม่ได้อยู่ในทุกS(multiplicities นับ) L - sum(S)มีระยะเวลาอย่างเคร่งครัดมากกว่า ผลลัพธ์ของคุณจะเป็นผลรวมที่น้อยที่สุดที่เป็นไปได้ของกำหนดการที่ถูกต้อง กล่าวอีกนัยหนึ่งคุณจะแสดงจำนวนหน่วยเวลาที่น้อยที่สุดที่คุณต้องทำงานในวันนี้

ตัวอย่าง

พิจารณาอินพุต

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

วิธีหนึ่งในการกำหนดวันของคุณคือ[4,4]: คุณทำงานสองอย่างให้เสร็จใน 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

    • SและTเหมือนกัน

    ตอนนี้ตัวกรองT (ลองเรียกมันว่าT ' ) ตอนนี้มีรายการงานทั้งหมดที่ทำงานเพียงพอ (หรือทำงานล่วงเวลาบ้าง)

  3. จากSทั้งหมดในT 'ให้เลือกอันที่มีผลรวมต่ำสุด

มันทำงานอย่างไร

Œ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 ไบต์

JEhSsMf&gJsT>hS.-QT-JsTyQ

ลองออนไลน์ ชุดทดสอบ

ฉันไม่สามารถเรียกใช้สองกรณีทดสอบล่าสุด (พวกเขาหมดเวลาออนไลน์ฉันถือว่า) แต่คนอื่น ๆ ทั้งหมดทำงาน นี่เป็นเพียงวิธีแก้ปัญหาพื้นฐานกำลังดุร้าย


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.