เยี่ยมชมจุดบนเส้นจำนวนในขณะที่ลดค่าใช้จ่ายที่ไม่เกี่ยวข้องกับระยะทาง


18

ฉันต้องการความช่วยเหลือในปัญหา ICM ACM นี้ แนวคิดปัจจุบันของฉันคือการสร้างแบบจำลองนี้เป็นปัญหาเส้นทางที่สั้นที่สุดซึ่งอธิบายไว้ในคำชี้แจงปัญหา

ปัญหา

มีN = 1000ภาชนะบรรจุกากนิวเคลียร์ที่ตั้งอยู่ตามแนวเส้นจำนวน 1-D ที่แตกต่างจากตำแหน่งยกเว้น-500,000 to 500,000 x=0บุคคลได้รับมอบหมายให้รวบรวมถังขยะทั้งหมด แต่ละวินาทีที่ไม่ได้เก็บขยะก็จะปล่อยรังสีออกมา 1 หน่วย บุคคลนั้นเริ่มต้นที่x = 0และสามารถเคลื่อนย้าย1หน่วยทุกวินาทีและการรวบรวมขยะต้องใช้เวลาเล็กน้อย เราต้องการค้นหาปริมาณรังสีขั้นต่ำที่ปล่อยออกมาขณะรวบรวมภาชนะทั้งหมด

ตัวอย่างอินพุต:

4[-12, -2, 3, 7]ตู้คอนเทนเนอร์ที่ตั้งอยู่ที่

คำสั่งที่ดีที่สุดในการรวบรวมภาชนะเหล่านี้คือ[-2, 3, 7, -12]สำหรับการปล่อย50หน่วยขั้นต่ำ คำอธิบาย: บุคคลนั้นจะไป-2ใน 2 วินาทีและในช่วงเวลา2 unitsของการแผ่รังสีนั้นจะถูกปล่อยออกมา จากนั้นเขาก็ไปที่3(ระยะทาง:) 5เพื่อให้ถังปล่อย2 + 5 = 7หน่วยรังสี เขาใช้เวลา4ไม่กี่วินาทีที่จะได้รับไปx = 7ที่บาร์เรลที่ได้ปล่อยออก2 + 5 + 4 = 11หน่วย เขาใช้เวลาไม่19กี่วินาทีเพื่อไปยังx = -12จุดที่บาร์เรลปล่อย2 + 5 + 4 + 19 = 30หน่วย 2 + 7 + 11 + 30 = 50ซึ่งเป็นคำตอบ

หมายเหตุ

มีO(N!)ทางออกชัดเจน อย่างไรก็ตามฉันได้สำรวจวิธีโลภเช่นย้ายไปยังที่อยู่ใกล้ที่สุดหรือย้ายไปยังกลุ่มที่อยู่ใกล้ที่สุด แต่ก็ไม่ได้ผล

ฉันเคยคิดเกี่ยวกับปัญหานี้มาระยะหนึ่งแล้วและได้จัดทำแบบจำลองเป็นปัญหาการค้นหากราฟ:

  1. เราแทรก0เป็นตำแหน่งพื้นฐาน (นี่จะเป็นสถานะเริ่มต้น)
  2. จากนั้นเราจัดเรียงตำแหน่งจากน้อยไปหามากที่สุด
  3. จากนั้นเราจะทำ BFS / PFS ซึ่งstateประกอบด้วย
    • จำนวนเต็มสองจำนวนlและrนั่นหมายถึงช่วงที่ต่อเนื่องกันในอาร์เรย์ตำแหน่งที่เรียงลำดับซึ่งเราได้เข้าชมแล้ว
    • จำนวนเต็มที่locบอกเราว่าเราอยู่ทางด้านซ้ายหรือขวาของช่วง
    • จำนวนเต็มที่timeบอกเวลาที่เราผ่านไป
    • จำนวนเต็ม 'ต้นทุน' ที่บอกเราถึงค่าใช้จ่ายทั้งหมดจนถึงขณะนี้ (ขึ้นอยู่กับโหนดที่เราเคยเยี่ยมชม)
  4. จากแต่ละสถานะเราสามารถย้ายไปที่ [l - 1, r] และ [l, r + 1], tweaking อีก 3 จำนวนเต็มตามลำดับ
  5. สถานะสุดท้ายคือ [0, N] ตรวจสอบตำแหน่งสิ้นสุดทั้งสอง

อย่างไรก็ตามดูเหมือนว่า[L, R, loc]จะไม่ได้กำหนดสถานะที่ไม่ซ้ำกันและเราต้องจัดเก็บL, R, loc, and timeในขณะที่ลดลงcostในแต่ละเหล่านี้ สิ่งนี้นำไปสู่อัลกอริธึมแบบเอ็กซ์โปเนนเชียลซึ่งยังคงช้าเกินไปสำหรับผลดีใด ๆ

ใครสามารถช่วยฉันขยายความคิดของฉันหรือผลักดันฉันไปในทิศทางที่ถูกต้อง?

แก้ไข:บางทีนี่อาจเป็นรูปแบบเป็นปัญหาการเพิ่มประสิทธิภาพการเขียนโปรแกรมแบบไดนามิก? เมื่อนึกถึงมันมีปัญหาเช่นเดียวกับวิธีแก้ปัญหาการค้นหากราฟ - เนื่องจากกระแสไฟฟ้าcostต่ำไม่ได้หมายความว่ามันเป็นคำตอบที่ดีที่สุดสำหรับปัญหาย่อยนั้นเนื่องจากtimeมีผลกระทบต่อคำตอบอย่างมากเช่นกัน

โลภไม่ทำงาน: ฉันมีอัลกอริธึมการเลือกโลภที่ประเมินค่าใช้จ่ายในการย้ายไปยังสถานที่หนึ่ง (เช่นถ้าเราย้ายไปทางขวา

คุณสามารถค้นหาด้วยลำดับความสำคัญก่อนด้วยการเรียนรู้แบบฮิวริสติกหรือไม่? ฮิวริสติกสามารถรวมค่าใช้จ่ายของการเดินทางปัจจุบันกับจำนวนเวลาที่ผ่านไป


ขั้นตอนวิธีเส้นทางที่สั้นที่สุด? เช่นเดียวกับอัลกอริทึมของ Dijkstra?
suraj_fale

ฉันลองมัน แต่ฉันคิดว่าฉันทำอะไรผิดไป ฉันอธิบายอัลกอริทึมของฉัน (ซึ่งเป็นลำดับความสำคัญการค้นหาครั้งแรกหรือ BFS) ใกล้ด้านล่างพร้อมรายการหมายเลข
Barron W.

สิ่งนี้อาจช่วยคุณได้ ... stackoverflow.com/q/14639346/585398
suraj_fale

ขออภัยฉันไม่เห็นว่าปัญหาทั้งสองเกี่ยวข้องกันอย่างไร คุณสามารถอธิบาย?
Barron W.

2
นี่เป็นปัญหาการปฏิบัติของ ACM ICPC ไม่ใช่ปัญหาชีวิตจริง ในบันทึกอื่นฉันพยายามลดสถานะ แต่ไม่เป็นประโยชน์ ฉันพยายามเขียนวิธีแก้ปัญหา DP แต่นั่นก็ไม่ได้ผลเหมือนกัน สถานะคือ L, R, POS
Barron W.

คำตอบ:


4

ฉันคิดว่าคุณสามารถปรับปรุงสิ่งนี้ได้โดยดูที่ปัญหาเป็นกราฟกำกับตำแหน่งคู่

สำหรับตัวอย่างนี้ฉันจะใช้บรรทัดที่มีค่า -9, -6, -1, 3 และ 5

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

ค่าก็สามารถจะคำนวณเป็นระยะห่างระหว่างสองจุดคูณด้วยจำนวนของถังด้านนอกของทั้งสองจุด + 1 เซลล์ที่ตัวเลขทั้งสองมีเครื่องหมายเหมือนกันแสดงถึงกรณีเมื่อบาร์เรลทั้งหมดที่มีเครื่องหมายตรงข้ามถูกรวบรวม สิ่งเหล่านี้คำนวณโดยใช้จำนวนบาร์เรลในทิศทางที่ห่างจากศูนย์

ในค่าตารางของ X หมายความว่าคุณไม่สามารถไปในทิศทางนั้นได้ (บาร์เรลทั้งหมดในทิศทางนั้นถูกนำไปใช้) แถวแสดงถึงตำแหน่งปัจจุบันของนักสะสมและคอลัมน์แสดงถึงที่ตั้งของบาร์เรลตรงข้ามต่อไป

    +------+------+------+------+------+
    |  -9  |  -6  |  -1  |   3  |   5  |
+---+------+------+------+------+------+
|-9 |      |      |      | X, 24| X, 14|
+---+------+------+------+------+------+
|-6 | 3, X |      |      | 9, 27| 6, 22|
+---+------+------+------+------+------+
|-1 |      |10, X |      |20, 8 |15, 18|
+---+------+------+------+------+------+
| 3 |24, 4 |27, 6 |16, 8 |      | X, 2 |
+---+------+------+------+------+------+
| 5 |14, X |22, X |18, X |      |      |
+---+------+------+------+------+------+

กฎสำหรับการเคลื่อนที่ระหว่างสแควร์สอาจค่อนข้างสับสน

สำหรับคอลัมน์ที่มีหมายเลขเชิงลบกฎมีดังนี้:

  • ไปทางขวาจะเลื่อนลงหนึ่งเซลล์
  • ไปทางซ้ายจะเลื่อนลงหนึ่งเซลล์แล้วสะท้อนข้ามเส้นทแยงมุม
  • หากค่าที่ถูกต้องคือ X การเลื่อนไปทางซ้ายจะขึ้นไปตามแนวทแยงมุม (โดยที่คอลัมน์และแถวเท่ากัน) และปล่อยทีละหนึ่ง

สำหรับคอลัมน์ที่มีหมายเลขบวกกฎจะเป็นดังนี้:

  • ไปทางซ้ายเลื่อนขึ้นหนึ่งเซลล์
  • ไปทางขวาเลื่อนขึ้นหนึ่งเซลล์แล้วสะท้อนข้ามเส้นทแยงมุม
  • หากค่าซ้ายคือ X การเลื่อนไปทางขวาเลื่อนลงไปในแนวทแยงมุม

ตอนนี้เราสามารถเรียกใช้อัลกอริทึมของ Dijkstra เพื่อคำนวณเส้นทางที่ดีที่สุดโดยใช้กฎการเคลื่อนที่เหล่านี้เพื่อสำรวจกราฟ ตำแหน่งเริ่มต้นของเราคือ (-1, 3) และ (3, -1) โดยมีราคาเริ่มต้นที่ 5 และ 15 ตามลำดับ เมื่อเราคำนวณค่าสำหรับตำแหน่งสิ้นสุดทั้งสอง (ด้านซ้ายของ (-9, -9) และด้านขวาของ (5, 5)) ขนาดที่เล็กกว่าของทั้งสองคือคำตอบของเรา

เวลาทำงานสำหรับแต่ละขั้นตอนคือ:

  • O (N log N) สำหรับการเรียงลำดับค่าอินพุตตามบรรทัด
  • O (N ^ 2) สำหรับการคำนวณตาราง / กราฟ
  • O (N ^ 2 log N) สำหรับการเรียกใช้ Dijkstra's บนกราฟ (หมายเหตุ: มีขอบไม่เกินสองจุดสำหรับจุดสุดยอดที่กำหนด)

สองขั้นตอนแรกถูกครอบงำด้วยสุดท้ายดังนั้นรันไทม์โดยรวมของคุณคือ O (N ^ 2 log N) ซึ่งน่าจะเพียงพอสำหรับการท้าทาย


1

ระยะทางที่สั้นที่สุด

ฉันเขียนแอปพลิเคชัน Java เมื่อวานนี้เพื่อแก้ปัญหา ปัญหานี้เป็นปัญหาระยะทางที่สั้นที่สุดตามที่ SRJ กล่าวในความคิดเห็นของเขา รังสีแสดงให้เห็นว่าคุณสามารถสะสมค่าพร้อมกับระยะทางที่สั้นที่สุด

นี่คือสิ่งที่ฉันทำ

  • ใส่หมายเลขคอนเทนเนอร์ในรายการ <Integer>
  • ในขณะที่รายการมีองค์ประกอบ;
    • ค้นหาองค์ประกอบที่ใกล้เคียงที่สุด
    • หากมีองค์ประกอบหนึ่งให้เดินไปที่นั่นแล้วลบองค์ประกอบนั้นออก
    • หากมีสององค์ประกอบให้คัดลอกเส้นทางและเดินไปที่องค์ประกอบทั้งสอง
  • ค้นหาเส้นทางด้วยค่ารังสีที่เล็กที่สุด

นี่คือผลลัพธ์บางส่วนจากแอปพลิเคชัน

10 containers are located at [-90, -75, -47, -9, 9, 26, 48, 50, 64, 79].

You walk to position -9 and pick up the container.  The total radiation emitted is 90 units.
You walk to position 9 and pick up the container.  The total radiation emitted is 252 units.
You walk to position 26 and pick up the container.  The total radiation emitted is 388 units.
You walk to position 48 and pick up the container.  The total radiation emitted is 542 units.
You walk to position 50 and pick up the container.  The total radiation emitted is 554 units.
You walk to position 64 and pick up the container.  The total radiation emitted is 624 units.
You walk to position 79 and pick up the container.  The total radiation emitted is 684 units.
You walk to position -47 and pick up the container.  The total radiation emitted is 1,062 units.
You walk to position -75 and pick up the container.  The total radiation emitted is 1,118 units.
You walk to position -90 and pick up the container.  The total radiation emitted is 1,133 units.

ฉันไม่ได้เพิ่มประสิทธิภาพอัลกอริทึม แต่อย่างใด ฉันไม่ได้สังเกตด้วยซ้ำว่ามีการเรียงลำดับรายการตัวเลข (ฉันเป็นคนโง่)

เมื่อฉันรันโค้ดด้วยค่าสูงสุด 1,000 คอนเทนเนอร์และช่วงจาก -500,000 ถึง 500,000 โค้ดของฉันใช้เวลาในการรัน 3 วินาที เวลาส่วนใหญ่เขียน 1,000 บรรทัดการพิมพ์ไปยังคอนโซล

ฉันไม่ใช่คน O ตัวใหญ่ แต่ฉันคิดว่ากำลังดุร้ายของฉันที่เดินตามอัลกอริธึมเส้นทางที่สั้นที่สุดคือ O (N กำลังสอง) ไม่ใช่ O (N!)

หากฉันใช้ประโยชน์จากความจริงที่ว่ามีการเรียงลำดับหมายเลขอินพุตดังนั้นฉันจึงต้องตรวจสอบตัวเลขทั้งสองที่ด้านที่ฉันอยู่ในปัจจุบันฉันสามารถทำให้แอปพลิเคชันอยู่ใกล้กับ O (N) ฉันต้องตรวจสอบตัวเลข 2 ตัวเพราะฉันลบองค์ประกอบออกจากรายการตามที่ได้รับไป

คุณใช้อัลกอริทึมที่แตกต่างกันเช่นอัลกอริทึมโลภเพื่อค้นหาวิธีแก้ไขปัญหาโดยประมาณ

หากโปรแกรมของฉันใช้เวลา 3 ชั่วโมงในการทำงานแทน 3 วินาทีคุณก็มีทางเลือกให้เลือก

ทางออกที่ดีคือดีพอหรือไม่?

กล่าวอีกนัยหนึ่งฉันยินดีแลกเปลี่ยนความเร็วในการประมวลผลสำหรับคำตอบที่ดีเพียงพอหรือไม่?

หากคำตอบที่ดีพอดีพอแล้วคุณก็ใช้อัลกอริธึมการประมาณ

หากคุณต้องการคำตอบที่สมบูรณ์แบบคุณต้องเดินไปตามเส้นทางที่สั้นที่สุด ไม่มีทางลัด

หากใครต้องการให้ฉันโพสต์รหัสของฉันฉันจะ ฉันแน่ใจว่ายังคงมีข้อบกพร่องตามที่ฉันต้องการเพื่อดูว่าฉันสามารถใช้อัลกอริธึมการเดินที่สั้นที่สุดได้หรือไม่


1

ฉันมีวิธีแก้ปัญหาที่จะแก้ปัญหานี้ใน2^Nเวลาที่ไม่ดี แต่ฉันคิดว่ามันเป็นวิธีที่มีประโยชน์ในการกำหนดกรอบปัญหาดังนั้นฉันคิดว่าฉันจะโพสต์

แทนที่จะทำแบบจำลองปัญหาเป็นกราฟฉันจะสร้างแบบจำลองมันเป็นแผนผังการตัดสินใจแบบไบนารี (พูดT) ในแต่ละระดับคุณจะต้องเลือกระหว่างการไปทางซ้ายหรือขวา มันค่อนข้างง่ายในการคำนวณ 'ต้นทุน' ของแต่ละขอบ อนุญาตh(K)จะเป็นความสูงของโหนดปัจจุบันแล้วค่าใช้จ่ายของขอบไปK left_child(K) = h(K) x dist(K, left_child(K))การคำนวณที่คล้ายกันพอเพียงสำหรับค่าใช้จ่ายของขอบกับลูกที่เหมาะสม คุณสร้างต้นไม้นี้และติดตามต้นทุน cummulative ของ edge ตลอดจนรายงานเส้นทางไปยังโหนดใบไม้ด้วยต้นทุนรวมที่น้อยที่สุด

โปรดทราบว่าการคำนวณค่าใช้จ่ายใช้งานได้เนื่องจากความยาวของแต่ละขอบdist(K, left_child(K))แสดงเวลาที่จะไปยังไซต์ถัดไปในขณะที่ความสูงของทรีย่อยคือจำนวนของไซต์ที่เหลือ (เช่นยังเปล่งรังสี)

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

มีหลายคนเสนอให้ใช้การแก้ปัญหาเส้นทางที่สั้นที่สุดสำหรับกราฟฉันมีข้อสงสัยบางอย่างเกี่ยวกับวิธีการแก้ปัญหาดังกล่าวสามารถทำงานได้ เพื่อนบ้านของคุณใน 'กราฟ' ในปัญหาจะเปลี่ยนไปตามเส้นทางที่คุณติดตาม ตัวอย่างเช่นในโพสต์ต้นฉบับของคุณด้วย[-12, -2, 3, 7]ถ้าคุณไป-2แล้ว-12และ3กลายเป็น 'เพื่อนบ้าน' และถ้าคุณไป3แล้ว-2และ7เป็นเพื่อนบ้าน 'คู่' ที่เป็นไปได้ของค่าบวกและค่าลบอาจเป็น neigbhours ในกราฟสุดท้าย ฉันไม่รู้อัลกอริธึมของพา ธ ที่สั้นที่สุดที่ถูกต้องในกราฟไดนามิก


0

ฉันคิดว่ามันสมเหตุสมผลที่จะคิดถึงทุกขั้นตอนอย่างง่าย ๆ ว่าเป็นตัวเลือกไบนารีระหว่างการไปทางขวาไปยังบาร์เรลที่ใกล้ที่สุดและไปทางซ้ายไปยังบาร์เรลที่ใกล้ที่สุด เพียงแค่มีฟังก์ชั่นค่าใช้จ่ายที่ให้รายละเอียดจำนวนหน่วยรังสีที่จะเกิดขึ้นทั้งหมดโดยทำการเคลื่อนที่ใด ๆ และเลือกหน่วยที่มีต้นทุนต่ำที่สุด

อย่าคิดเพียงบาร์เรลที่อยู่ใกล้ที่สุด แต่สมมติว่าโดยการย้ายออกจากถังคุณจะเพิ่มการแผ่รังสีได้อย่างมีประสิทธิภาพเป็นสองเท่าเพราะการย้ายออกไปทำให้คุณต้องเสียค่าใช้จ่ายในการเลื่อนกลับทิศทางนั้นในภายหลัง

ในตัวอย่างของคุณที่ [-12, -2,3,7] การเลื่อนไปทางซ้ายจะมีทั้งหมด 14 (2 + 2 + 10) ทางซ้ายและ 18 (2 + 2 + 5 + 9) ทางขวา รวมเป็น 22 การเคลื่อนที่ขวาจะมี 10 (3 + 3 + 4) ทางขวาและ 26 (3 + 3 + 5 + 15) ทางขวา ตอนแรกทางซ้ายชัดเจนคือทางออกที่ถูกต้อง การคำนวณที่คล้ายกันสามารถทำได้สำหรับทุกการเคลื่อนไหวต่อเนื่อง

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

เห็นได้ชัดว่าฉันไม่ชัดเจนเพียงพอกับคำอธิบายนี้ดังนั้นฉันตัดสินใจที่จะทำให้โปรแกรมเพิ่มขึ้นอีกเล็กน้อย: 1. คำนวณต้นทุนที่เกิดจากการไปทางซ้ายและต้นทุนที่เกิดขึ้นโดยไปทางขวาตามตำแหน่งปัจจุบัน 2. ย้ายเข้า ทิศทางที่ถูกที่สุดอย่างน้อยที่สุด 3. นำกระบอกสูบออกจากการพิจารณาในการคำนวณค่าใช้จ่ายในการเคลื่อนที่ในทิศทาง

การคำนวณต้นทุน: 1. ระบุกระบอกที่ใกล้ที่สุดในทิศทางที่กำหนด สมมติว่า $ dist คือระยะทางจากตำแหน่งปัจจุบันไปยังบาร์เรลที่ใกล้ที่สุดในทิศทางที่กำหนด 2. ราคาถูกกำหนดค่าเริ่มต้นเป็น N * $ dist โดยที่ N พิจารณาเฉพาะบาร์เรลที่ยังทำงานอยู่เท่านั้น 3. ในการนี้เพิ่มระยะทางที่ตำแหน่งใหม่ที่ระบุโดย $ dist จะมาจากทุกบาร์เรลที่เหลือ


1
มันไม่ได้ผลเสมอไป บางทีคุณสามารถเรียงลำดับ coords แล้วค้นหาที่รัฐมีช่วง [i..j] (ซึ่งหมายถึงช่วงที่คุณเคยเยี่ยมชม) และต้นทุนและเวลาปัจจุบัน
Barron W.

สิ่งนี้ไม่ทำงานเมื่อไหร่?
Slater Victoroff

มีกรณีทดสอบง่ายๆที่สิ่งนี้ล้มเหลว ฉันจะพยายามหามัน แต่มันคือ N = 4 หรือ 5
Barron W.

[43, -18, -98, -82, 63]
Barron W.

[-10,-11, 10,20,30,40,50,60,70]นอกจากนี้ยังมีกรณีเช่น วิธีการแก้ไขที่ถูกต้องเพียงอย่างเดียวคือการรวบรวมสิ่งที่เป็นลบทั้งหมดจากนั้นก็เก็บผลบวก สำหรับคำตอบที่ 455
Barron W.

0

ทางออกบางส่วน - ฉันจะกลับไปหามันในภายหลัง

สมมติว่ากลยุทธ์ "เริ่มต้น" นั้นวิ่งไปทางซ้ายหรือขวาแล้วแต่ว่าจะถูกอะไร ทีนี้ถามว่ามันคุ้มค่าที่จะเดินทางไปอีกทางหนึ่งเพื่อซื้อถังหนึ่งหรือไม่ การคำนวณคำตอบนั้นค่อนข้างง่าย

สำหรับอินพุตตัวอย่างของคุณการวิ่งไปทางขวานั้นถูกกว่าทางซ้ายทั้งหมด จะ -2 คุ้มค่าการเดินทางด้าน? มันลดค่าใช้จ่ายในการวิ่งไปทางขวาแล้วกลับมาที่ 0 จาก 14 (เพราะคุณ "จ่าย" 4 หน่วยรังสีต่อการย้ายจาก 0 ถึง 3 ตามกลยุทธ์เริ่มต้นตอนนี้มันลดเหลือ 3 คุณจ่าย 3 จาก 3 ถึง 7 ตอนนี้มันคือ 2 ฯลฯ ) บวกกับลดลงหนึ่งรายการต่อการย้ายค่าใช้จ่ายในการย้ายจาก 0 ถึง -2 ดังนั้นจึงประหยัด 2 ได้มากขึ้นทั้งหมด 16 รายการ

อย่างไรก็ตามจะเพิ่มค่าใช้จ่ายเป็น -2 จากนั้นกลับเป็น 0 ของ 14 (4 หน่วยต่อการย้ายเป็น -2, 3 ต่อการย้ายกลับเป็น 0) สำหรับกำไรสุทธิที่ (16-14) = 2 โปรดทราบว่าในการคำนวณสิ่งนี้คุณไม่จำเป็นต้องประเมินค่าใช้จ่ายที่ถูกต้องในการแก้ปัญหาทั้งหมดสำหรับการตัดสินใจแต่ละครั้ง - คุณมีข้อมูลเพียงพอที่จะตัดสินใจเพียงแค่รู้ว่าการวิ่งไปทางซ้ายนั้นถูกกว่าการวิ่งไปตลอดทาง ถังขยะจำนวนมากอยู่ข้างคุณและระยะทางไปยังจุดที่ใกล้ที่สุด 2 นั่นคือ O (N ^ 2)

ยกเว้นปัญหาที่สำคัญอย่างหนึ่ง - ฉันถือว่าคุณจะวิ่งไปจนสุดทางและเรารู้ว่าคุณอาจถอยกลับมาเป็นสองเท่า เพื่อล้างข้อมูลนั้นเราต้องอัปเดตการคำนวณของฉัน สำหรับตัวอย่างอินพุตฉันสันนิษฐานว่าคุณจะประหยัดได้ 14 โดยปล่อยรังสีรวมน้อยกว่า 1 ต่อหน่วยต่อวินาทีในขณะที่วิ่งจาก 0 ถึง 7 และย้อนกลับ แต่ถ้าคุณกลับเป็นสองเท่าก่อนที่จะวิ่งไปที่ 7 การออมจะลดลง

นั่นเป็นเรื่องที่ค่อนข้างแย่เพราะฉันไม่รู้วิธีคำนวณการตีกลับครั้งถัดไปโดยไม่ลองความเป็นไปได้ทั้งหมดซึ่งทำให้เรากลับไปที่ O (2 ^ N)

ยกเว้น - มันคือ 2 ^ N ที่มีการตัดแต่งกิ่ง ฉันคำนวณว่า "การเดินทางด้านข้าง" เป็น -2 ราคา 14 แต่เพิ่มขึ้น 16 ถ้าฉันไม่มีการเดินทางด้านข้างเพิ่มเติมก่อนที่ฉันจะทำมันให้ถูกที่สุด ถ้าจำนวนที่ถูกต้องที่สุดคือ 5 ฉันจะรู้ทันทีว่าการเดินทางด้านข้างเพื่อ -2 ไม่สามารถชำระได้ (ค่าใช้จ่ายยังคง 14 ผลประโยชน์สูงสุด 12) ฉันไม่ต้องคิดว่าจะไป -2 จากนั้นจึงออกเดินทางด้านข้างก่อนถึงอายุ 6 ขวบเนื่องจากมันด้อยกว่าเสมอไปตรงจุดนั้นตั้งแต่แรก


0

ฉันคิดว่าคุณสามารถแก้ปัญหาได้โดยใช้การค้นหาแบบกว้างก่อนและรักษาไม่เกิน 2 * N ^ 2 tuples ของ (บูลีน, int, int, int, string) ที่สตริงมีความยาวตราบเท่าที่เส้นทางมีความซับซ้อน

สิ่งอันดับคือ (บูลีนต่ำสุดหรือสูงสุด, ตำแหน่งต่ำสุดเดินทาง, ตำแหน่งสูงสุดเดินทาง, ปริมาณรังสีทั้งหมดที่ปล่อยออกมา, ประวัติเส้นทาง)

ฉันเห็นอัลกอริทึมเป็นดังนี้:

  1. เริ่มต้นพูลของสิ่งอันดับเป็นรายการเดียว, (min, 0, 0, 0, ",)
  2. ค้นหาองค์ประกอบในสระว่ายน้ำที่ปล่อยรังสีน้อยที่สุด หากขั้นต่ำและสูงสุดสอดคล้องกับขั้นต่ำและสูงสุดของบาร์เรลทั้งหมดประวัติของเส้นทางคือทางออกที่ดีที่สุด มิฉะนั้นลบออกจากสระว่ายน้ำ
  3. คำนวณลูกหลาน 2 คนของ tuple นี้ซึ่งแต่ละตัวสอดคล้องกับการเดินไปทางซ้ายหรือขวาไปยังบาร์เรลที่ยังไม่ได้ประมวลผลถัดไป
  4. แทรกลูกหลานลงในสระว่ายน้ำ หากมีองค์ประกอบอยู่ในสระที่มีบูลีนเดียวกัน min และ max เหมือน descendent ใหม่ให้ละทิ้งองค์ประกอบที่มีจำนวนรังสีสูงกว่า
  5. ข้ามไป 2

การค้นหาและลบสิ่งอันดับเด่นจะช่วยปรับปรุงประสิทธิภาพได้อย่างมาก มันอาจคุ้มค่าที่จะเพิ่มเครื่องหมาย 'has bred' ลงในแต่ละ tuple และปล่อยให้ tuples นั้นอยู่ในสระ

นอกจากนี้ยังมีการตัดสินใจที่สำคัญบางอย่างในการตัดสินใจว่าจะเก็บสิ่งอันดับอย่างไรและค้นหาสิ่งเหล่านั้นเพื่อหาการปกครองและองค์ประกอบใหม่ที่จะผสมพันธุ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.