คุณระบุปัญหาว่าเหมาะสำหรับการเขียนโปรแกรมแบบไดนามิกอย่างไร


19

ฉันได้อ่านการเขียนโปรแกรมแบบไดนามิกเมื่อเร็ว ๆ นี้ อยากได้ยินจากคนที่เริ่มต้นจากศูนย์และตอนนี้ก็ค่อนข้างดีในการระบุและแก้ไขปัญหา DP ฉันกำลังดิ้นรนในการระบุปัญหาเหล่านี้เป็น DP และกำหนดวิธีการแก้ปัญหาที่รัดกุม

ฉันได้ผ่านปัญหา DP ส่วนใหญ่สำหรับผู้เริ่มต้นและทรัพยากร MIT แล้ว

คำตอบ:


17

ฉันมาจากภูมิหลังทางฟิสิกส์และคณิตศาสตร์จำนวนมาก ผมพบว่าง่ายต่อการมองเห็นปัญหาที่ดีเหมาะแก่การแก้ปัญหาการเขียนโปรแกรม recursive / แบบไดนามิกโดยการค้นหาความคล้ายคลึงกันกับหลักฐานโดยการเหนี่ยวนำ

ในการพิสูจน์โดยอุปนัยคุณมีสองส่วน

  • คุณพิสูจน์ว่าหากสิ่งที่เป็นจริงสำหรับการทำซ้ำ N มันก็เป็นความจริงสำหรับการทำซ้ำ N + 1
  • คุณพิสูจน์ว่ามันเป็นความจริงสำหรับการวนซ้ำ 1

ในการโปรแกรมแบบเรียกซ้ำ / การเขียนโปรแกรมแบบไดนามิก:

  • คุณระบุเงื่อนไขการออก (ตัวอย่างเช่นคุณใช้วิธีแก้ปัญหาสำหรับการวนซ้ำ 1)
  • คุณคำนวณวิธีแก้ปัญหาสำหรับการทำซ้ำ N กำหนดวิธีแก้ปัญหาสำหรับการทำซ้ำ N-1

ดังนั้นตามที่คนอื่น ๆ ตอบมันเป็นเรื่องของประสบการณ์และการเลือกคำแนะนำ แต่คุณสามารถใช้ทักษะอื่น ๆ เพื่อเป็นแนวทางให้คุณได้ หลังจากนั้นคุณต้องมีสองส่วนที่ฉันพูดถึงเสมอ: ถ้าคุณทำไม่ได้มันจะไม่ทำงาน

ตัวอย่างเช่นในการสร้างพีชคณิตทั้งหมดของชุด:

  • เงื่อนไขทางออก: หากคุณมีองค์ประกอบเดียวให้ส่งคืน
  • การเรียกซ้ำ: การเรียงสับเปลี่ยนของชุดรายการ N คือชุดเรียงสับเปลี่ยน N ชุดที่คุณได้รับโดยการเลือกแต่ละองค์ประกอบและรวมกับการเรียงสับเปลี่ยนของชุดย่อย N-1 ทั้งหมดที่คุณได้รับโดยการเอาองค์ประกอบออก

8

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

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

TL; DR; เวอร์ชั่น: คุณอาจเข้าใจการเขียนโปรแกรมแบบไดนามิกได้ง่ายขึ้นในแง่ของการบันทึก

ดูเพิ่มเติมStackOverflow: การเขียนโปรแกรมแบบไดนามิกและการบันทึกช่วยจำ: วิธีการจากบนลงล่างและจากบนลงล่าง


4

การเขียนโปรแกรมแบบไดนามิกมีความหมายเกี่ยวกับสองสิ่ง:

  1. โครงสร้างย่อยที่เหมาะสม
    ทางออกที่ใหญ่กว่านั้นสามารถหาได้จากโซลูชันที่เล็กกว่า การแก้ไม่ใช่แบบสองทิศทาง

  2. ปัญหาย่อยที่ทับซ้อนกัน
    โซลูชันขนาดเล็กจะถูกนำมาใช้ซ้ำหลายครั้ง หากปัญหาย่อยไม่ทับซ้อนกันคุณจะไม่ได้รับประโยชน์จาก DP / การจำ สิ่งที่คุณมีคือการแบ่งและพิชิตแทน

วิธีการทั่วไปในการแก้ไขปัญหา DP คือ:

  • เขียนเวอร์ชันซ้ำหรือแบบซ้ำ ๆ ที่ใช้งานได้

  • โปรดสังเกตว่าฟังก์ชันกำลังทำงานซ้ำซ้อน

  • ค้นหาวิธีหลีกเลี่ยงการทำงานซ้ำซ้อนบ่อยครั้งโดยการจำ


ทั้งหมดนี้เป็นจริงจากจุดยืนเชิงทฤษฎี IMO จำเป็นต้องฝึกฝนเพิ่มอีกเล็กน้อยเพื่อให้คุ้นเคยกับการระบุตัวตนอย่างรวดเร็วยิ่งขึ้น :)
11,0036

2

ฉันไม่เคยใช้ตัวแก้ปัญหาการเขียนโปรแกรมแบบไดนามิกเดียว - พื้นหลังของฉันใช้คณิตศาสตร์ / ฟิสิกส์ / การคำนวณเชิงตัวเลขไม่ใช่ CS - จนกระทั่งไม่กี่ปีที่ผ่านมาเมื่อฉันเริ่มทำปัญหาProject Euler ปัญหาที่แก้ปัญหา DP ได้ (เช่น76 , 158 , 161 , 242แต่มีอีกมากมาย) กลายเป็นคนที่ฉันชอบมาก คุณจะดีขึ้นอย่างแน่นอนเมื่อพบว่ามันจะเป็นเทคนิคที่มีประโยชน์: โดยทั่วไปมองหาสิ่งต่าง ๆ ที่ดูเหมือนว่าพวกเขาสามารถแก้ไขได้ด้วยวิธีการแบบวนซ้ำแบบแบ่งและพิชิตซึ่งเป็นไปได้ที่จะเชื่องการระเบิดของเส้นทางที่ต้องการ ที่จะสำรวจโดยการรับรู้ปัญหาย่อยที่เกิดขึ้นและนำผลการคำนวณก่อนหน้านี้; ความสามารถในการระบุเวกเตอร์สถานะขั้นต่ำที่จะบันทึก - และ "ประวัติ" ที่ไม่เกี่ยวข้องซึ่งสามารถลบได้ - เป็นขั้นตอนสำคัญ

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