นี่คือคำแนะนำเพื่อให้คุณเริ่มต้น ใช้อัลกอริธึมการเขียนโปรแกรมแบบไดนามิกมาตรฐานสำหรับการแจกแจงชุดพาร์ติชันของจำนวนเต็มและเพิ่มตรรกะบางอย่างเพื่อตรวจสอบว่าสิ่งใดที่อนุญาตให้ทำการเปลี่ยนแปลงที่ไม่ซ้ำกันโดยการตรวจสอบผลรวมซ้ำการเปลี่ยนแปลงและยืนยันเอกลักษณ์
ในรายละเอียดอีกเล็กน้อย: สมมติว่าคุณมี MultiSet S ได้รับหมายเลขฉันกับ1 ≤ ฉัน≤ nวิธีการที่คุณสามารถระบุ submultiset ของSที่จำนวนเงินที่จะฉัน ? คุณจะตรวจสอบได้อย่างไรว่าชุดข้อมูลย่อยนั้นไม่ซ้ำกัน พยายามที่จะปรับตัวเข้ากับเทคนิคการเขียนโปรแกรมแบบไดนามิกมาตรฐานสำหรับการเปลี่ยนแปลง (ดูคำถามนี้ด้วย)Sผม1 ≤ ฉัน≤ nSผม
รับ multiset Sคุณจะตรวจสอบได้อย่างไรว่ามันเป็นไปตามเงื่อนไขที่สองหรือไม่เช่นว่าทุกหมายเลขจาก 1 ถึงnสามารถแสดงได้โดยไม่ซ้ำกันเป็นผลรวมของซับเซ็ตย่อยของS (เงื่อนไขการเปลี่ยนแปลงที่ไม่ซ้ำกัน) นี่น่าจะง่ายถ้าคุณแก้ไขก่อนหน้านี้SnS
ให้P ( n )แสดงรายการของชุดมัลติที่ตรงตามเงื่อนไขของคุณ หากคุณรู้จักP ( 1 ) , P ( 2 ) , … , P ( n )คุณจะใช้ข้อมูลนั้นเพื่อสร้างP ( n + 1 ) ได้อย่างไร? ที่นี่คุณอาจต้องการปรับใช้เทคนิคการเขียนโปรแกรมแบบไดนามิกมาตรฐานสำหรับการระบุพาร์ติชันของจำนวนเต็มP( n )P( 1 ) , P( 2 ) , … , P( n )P( n + 1 )
นี่คือวิธีการที่อาจจะดีกว่า
สมมติว่าSเป็นมัลติเซ็ตที่ตอบสนองเงื่อนไขทั้งสองของคุณ (สำหรับn ) เราจะขยายมันเพื่อรับมัลติเซ็ตTที่มีองค์ประกอบหนึ่งมากกว่าได้อย่างไร ในคำอื่น ๆ วิธีการที่เราสามารถระบุวิธีการทั้งหมดเพื่อเพิ่มองค์ประกอบหนึ่งที่มากขึ้นในการSเพื่อให้ได้ MultiSet ใหม่Tที่ทั้งสองฝ่ายของเงื่อนไขของคุณ (บางn ' )?SnTSTn'
คำตอบ: ถ้าxสามารถแสดงเป็นผลรวมขององค์ประกอบบางอย่างของSดังนั้นจะไม่มีจุดเพิ่มลงในS : ซึ่งจะทำให้Tละเมิดเงื่อนไขที่ไม่ซ้ำกัน ดังนั้นเราสามารถแจกแจงจำนวนเต็มxทั้งหมดที่ไม่สามารถแสดงเป็นผลรวมขององค์ประกอบบางส่วนของS ; แต่ละอันเป็นสิ่งที่สามารถเพิ่มลงในSเพื่อรับมัลติเซตTใหม่ที่จะตอบสนองเงื่อนไขทั้งสอง (สำหรับnอื่น ๆ)xSSTxSSTn
ยิ่งไปกว่านั้นมันเป็นไปได้ที่จะระบุจำนวนเต็มที่สามารถแสดงเป็นผลรวมขององค์ประกอบบางอย่างของSและไม่สามารถใช้การเขียนโปรแกรมแบบไดนามิก คุณสร้างอาร์เรย์Aสองมิติ[ 1 … | S | , 1 ... n ]ของ booleans ที่[ ฉัน, J ]เป็นจริงถ้ามีวิธีที่จะแสดงความจำนวนเต็มเจเป็นผลรวมของบางส่วนของแรกฉันองค์ประกอบของS (เฉพาะครั้งแรกที่ฉันองค์ประกอบของSมีสิทธิ์ที่จะ ถูกนำมาใช้; ที่SSA[1…|S|,1…n]A[i,j]jiSiSSเรียงลำดับแล้วดังนั้นS = { s 1 , s 2 , … , s k }และs 1 ≤ s 2 ≤ ⋯ ≤ s k ) โปรดทราบว่าA [ i , j ]สามารถคำนวณได้โดยใช้ค่าของA [ 1 … i - 1 , 1 … j - 1 ] : โดยเฉพาะA [ i , j ]S={s1,s2,…,sk}s1≤s2≤⋯≤skA[i,j]A[1…i−1,1…j−1]= [ ฉัน- 1 , J ] ∨ [ ฉัน- 1 , J - s ฉัน ]ถ้า J > s ฉันหรือ [ ฉัน, J ] = [ ฉัน- 1 , J ]มิฉะนั้น ซึ่งจะช่วยให้เราสามารถระบุตัวเลขทั้งหมดที่มีผู้สมัครที่จะเพิ่มSA[i,j]=A[i−1,j]∨A[i−1,j−si]j>siA[i,j]=A[i−1,j]S
ถัดไปสำหรับแต่ละส่วนขยายของผู้สมัครTของS (ได้รับจากการเพิ่มองค์ประกอบหนึ่งไปยังS ) เราต้องการตรวจสอบว่าT เป็นไปตามเงื่อนไขทั้งสองหรือไม่ ให้nแสดงผลรวมขององค์ประกอบของSและn 'ผลรวมขององค์ประกอบของT เราจำเป็นต้องตรวจสอบว่าทุกจำนวนเต็มในช่วงn + 1 , n + 2 , … , n ′สามารถแสดงเป็นผลรวมขององค์ประกอบบางส่วนของTT. สิ่งนี้สามารถแก้ไขได้โดยใช้การเขียนโปรแกรมแบบไดนามิกโดยใช้อัลกอริธึมมาตรฐานสำหรับการเปลี่ยนแปลง (ในความเป็นจริงถ้าคุณยังมีอาร์เรย์ดังกล่าวข้างต้นคุณสามารถขยายได้นิด ๆ หน่อย ๆ เพื่อแก้ปัญหานี้: เราทำให้มันอาร์เรย์[ 1 ... | T | , 1 ... n ' ]ให้ดำเนินการต่อเพื่อเติมเต็มในทุก ของรายการเพิ่มเติมและตรวจสอบให้แน่ใจว่าA [ | T | , n + 1 ] , A [ | T | , n + 2 ] ,… , A [ | T | , n ′ ]เป็นจริงทั้งหมด) ดังนั้นตอนนี้เราสามารถแจกแจงมัลติเซต Tทั้งหมดที่ขยาย Sด้วยองค์ประกอบเดียวและเป็นไปตามเงื่อนไขทั้งสอง
นี้แสดงให้เห็นทันทีขั้นตอนวิธีการแจกแจงทุกมัลติSที่ตอบสนองเงื่อนไขของคุณสำหรับทุกnถึงบางผูกพันพูดn ≤ 20 เราจะมีอาร์เรย์P [ 1 ... 20 ]ที่P [ 5 ]ร้านค้าทั้งหมดมัลติSรวมที่ 5 และโดยทั่วไป, P [ n ]ร้านค้าชุดของมัลติทั้งหมดSรวมที่n
ต่อไปเราสามารถเติมP [ n ]ซ้ำได้ เริ่มต้นด้วยการตั้งค่าP [ 1 ]จะมีเพียงหนึ่ง MultiSet { 1 } ถัดไปสำหรับแต่ละn (นับจาก 1 ถึง 20) สำหรับแต่ละS ∈ P [ n ]แจกแจงส่วนขยายที่เป็นไปได้ทั้งหมดTของS (โดยใช้เทคนิคด้านบน) ให้n ′แสดงถึงผลรวมขององค์ประกอบของTและ แทรกTเป็นP [ n ′ ]ถ้ามันไม่ได้แล้วในปัจจุบันและถ้าn ' ≤ 20
นี่น่าจะทำได้ โชคดี! มีความสุข! การทำงานผ่านรายละเอียดจะเป็นการฝึกการเรียนรู้ที่ดีในการเขียนโปรแกรมแบบไดนามิก