การหาขนาดของเซตย่อยที่เล็กที่สุดด้วย GCD = 1


10

ปัญหานี้เป็นปัญหาจากการฝึกซ้อมของที่โปแลนด์วิทยาลัย Programming Contest 2012 แม้ว่าฉันจะสามารถหาวิธีแก้ปัญหาสำหรับการแข่งขันหลัก แต่ฉันไม่สามารถหาวิธีแก้ไขปัญหานี้ได้ทุกที่

ปัญหาคือ: เนื่องจากชุดของเลขจำนวนเต็มบวกNแตกต่างกันไม่เกิน109ให้หาขนาดmของเซตย่อยที่เล็กที่สุดที่ไม่มีตัวหารร่วมอื่นที่ไม่ใช่ 1 Nมากที่สุด 500 และสามารถหาวิธีแก้ปัญหาได้

ฉันจัดการเพื่อแสดงให้เห็นว่าm9 9 เหตุผลของฉันคือ: สมมติว่ามีเซตย่อยน้อยที่สุดของSขนาด|S|=10S1<g1<g2<...<g10gcd(gi,gj)=1ijSg2g3...g10g2g3...g103×5×7×11×...×29=3234846615>109ซึ่งขัดแย้งกัน

อย่างไรก็ตามแม้จะมีสิ่งนี้กำลังดุร้ายตรงไปตรงมาก็ยังช้าเกินไป ไม่มีใครมีความคิดอื่น ๆ อีกบ้าง?


whay ไม่สามารถ ? g2=2
vonbrand

g2>g122 ไม่สามารถเป็น 1 ได้เนื่องจาก 9 ชุดย่อยไม่สามารถมี gcd เป็น 1 ได้g1
Wakaka

คำตอบ:


1

ปัญหานี้เทียบเท่ากับสิ่งต่อไปนี้และเป็นเรื่องเล็กน้อยที่จะสร้างการลดลงทั้งสองวิธี

รับรายการบิตเวคเตอร์หาจำนวนขั้นต่ำสุดที่พวกมันandทั้งหมดส่งผลให้บิตเวกเตอร์ 0()

จากนั้นเราจะแสดงปกชุดลดไป(*)เมื่อตั้งค่าฝาครอบฉันหมายถึงให้รายการชุดค้นหาจำนวนชุดขั้นต่ำที่ครอบคลุมสหภาพของพวกเขา()S1,,Sk

เราสั่งองค์ประกอบในชุดที่จะa_1,ให้ , โดยที่ถ้า , 0 เป็นอย่างอื่น หมายเหตุฟังก์ชั่นนี้เป็น bijection ดังนั้นมันจึงมีค่าผกผันa1,,anf(S)=(1χa1(S),,1χan(S))χx(S)=1xS

ตอนนี้ถ้าเราแก้ในและการแก้ปัญหาคือแล้วเป็นวิธีแก้ไขปัญหา()f(S1),,f(Sk){f(Sb1),,f(Sbm)}{f1(Sb1),,f1(Sbm)}

ดังนั้นฉันคิดว่าปัญหานี้กำลังทดสอบความสามารถของคนในการตัดพื้นที่การค้นหา


คุณจะพบจุดสุดยอดขั้นต่ำครอบคลุมได้อย่างไร?
Yuval Filmus

โอ้ nvm วิธีนี้มันตั้งฝาครอบแทน
เจ้า Xu

1
นั่นเป็นความจริง แต่ฉันคิดว่าบางทีเราสามารถใช้ประโยชน์จากคุณสมบัติบางอย่างของคดีพิเศษนี้ได้ ยกตัวอย่างเช่นในกรณีนี้ชุดที่มีทั้งหมดขนาดใหญ่มากที่มีขนาดไม่น้อยกว่าn-9อันที่จริงถ้าตัวเลขในเซตมีขนาดเล็กทั้งหมดขนาดของมันจะใหญ่กว่านี้ นอกจากนี้เราสามารถพบ 9 ชุดที่ครอบคลุมทุกอย่าง อย่างไรก็ตามคุณจะแนะนำให้ฉันตัดพื้นที่การค้นหาได้อย่างไร n9
Wakaka

ฉันไม่เห็นว่าปัญหา (*) เทียบเท่ากับที่ให้ไว้ในคำถาม สำหรับสิ่งหนึ่งปัญหาที่ระบุในคำถามมีสัญญาว่าจำนวนเต็มทั้งหมดจะเป็นซึ่งสอดคล้องกับการรับประกันเกี่ยวกับน้ำหนักของบิตเวกเตอร์ที่ไม่ปรากฏในปัญหา (*) 109
DW

1

เป็นไปได้ที่จะแก้ปัญหานี้ได้อย่างมีประสิทธิภาพโดยการคำนวณ gcd ของ pairwise ทั้งหมด, ลบรายการที่ซ้ำกัน, จากนั้นเรียกซ้ำ เป็นการลบสิ่งที่ซ้ำกันออกก่อนที่คุณจะทำการคืนค่าให้มีประสิทธิภาพ

ฉันจะอธิบายขั้นตอนวิธีการในรายละเอียดด้านล่าง แต่แรกก็จะช่วยให้การกำหนดผู้ประกอบการไบนารี\ถ้าเป็นชุดของจำนวนเต็มบวก, defineS,T

ST={gcd(s,t):sS,tT}.

โปรดทราบว่าและ (ในปัญหาของคุณ); โดยทั่วไปจะมีขนาดเล็กกว่าขอบเขตที่แนะนำซึ่งช่วยให้อัลกอริทึมมีประสิทธิภาพ โปรดทราบว่าเราสามารถคำนวณได้|ST||S|×|T||ST|109STSTกับการดำเนินงาน gcd โดยการแจงนับง่าย|S|×|T|

ด้วยสัญกรณ์นั้นนี่คืออัลกอริทึม ให้เป็นชุดตัวเลข คำนวณแล้วจากนั้นและอื่น ๆ ค้นหาเล็กที่สุดที่แต่S1S2=S1S1S3=S1S2S4=S1S3k1Sk1Sk1{k-1} แล้วคุณจะรู้ว่าขนาดของชุดย่อยดังกล่าวมีขนาดเล็กที่สุดคือkหากคุณต้องการส่งออกตัวอย่างที่เป็นรูปธรรมของชุดย่อยดังกล่าวโดยการรักษาพอยน์เตอร์พอยน์เตอร์คุณสามารถสร้างชุดดังกล่าวขึ้นใหม่ได้อย่างง่ายดายk

สิ่งนี้จะมีประสิทธิภาพค่อนข้างมากเนื่องจากไม่มีชุดค่ากลางใดที่ขยายขนาดขึ้น 109 (อันที่จริงขนาดอาจจะเล็กกว่านั้น) และเวลาทำงานต้องใช้ประมาณการดำเนินการ gcd500×(|S1|+|S2|+)

นี่คือการเพิ่มประสิทธิภาพที่อาจปรับปรุงประสิทธิภาพยิ่งขึ้นไปอีก โดยทั่วไปคุณสามารถใช้ซ้ำสองเท่าเพื่อหาสิ่งที่เล็กที่สุดดังกล่าวที่S_k โดยเฉพาะอย่างยิ่งสำหรับแต่ละองค์ประกอบเราติดตามการย่อยที่เล็กที่สุดของมี GCD คือและขนาดซึ่งเป็นฉัน (เมื่อคุณลบรายการที่ซ้ำกันคุณแก้ไขความสัมพันธ์ในความโปรดปรานของเซตย่อยที่มีขนาดเล็กกว่า) ตอนนี้แทนที่จะคำนวณลำดับที่เก้าเซตแทนการคำนวณลำดับห้าชุดโดยการคำนวณจากนั้นk1SkxSiS1xiS1,S2,S3,S4,,S9S1,S2,S4,S8,S9S2=S1S1จากนั้นจากนั้นS4=S2S2S8=S4S4S9=S1×S8S_8 ขณะที่คุณไปพบครั้งแรกดังกล่าวที่S_k เมื่อคุณได้พบดังกล่าวที่คุณสามารถหยุดได้ทันที: คุณสามารถหาชุดย่อยที่เล็กที่สุดที่มี GCD เป็นโดยดูที่เซตที่เกี่ยวข้องกับการ1ดังนั้นคุณสามารถหยุดทันทีที่คุณมาถึงชุดที่ซึ่งจะช่วยให้คุณสามารถหยุดก่อนถ้าคุณพบชุดย่อยที่เล็กกว่าk[1,2,4,8,9]1Skk1Sk11Sk1Sk

สิ่งนี้ควรมีประสิทธิภาพด้านเวลาและประหยัดพื้นที่ เพื่อประหยัดพื้นที่สำหรับแต่ละองค์ประกอบคุณไม่จำเป็นต้องเก็บทั้งชุด: มันเพียงพอที่จะเก็บ backpointers สองตัว (ดังนั้นองค์ประกอบทั้งสองของที่คุณใช้ gcd ของเพื่อรับ ) และ เลือกขนาดของชุดย่อยที่สอดคล้องกันxSkSi,Sjx

ในหลักการที่คุณสามารถเปลี่ยนลำดับโดยอื่น ๆห่วงโซ่นอกจากนี้ ฉันไม่รู้ว่าห่วงโซ่การเติมอื่น ๆ จะดีกว่านี้หรือไม่ ตัวเลือกที่ดีที่สุดอาจขึ้นอยู่กับการกระจายของคำตอบที่ถูกต้องและขนาดที่คาดหวังของชุด[1,2,4,8,9]Skซึ่งไม่ชัดเจนสำหรับฉัน แต่อาจได้รับสังเกตุจากการทดลอง

เครดิต: ขอบคุณ KWillets สำหรับแนวคิดในการจัดเก็บชุดย่อยของตัวเลขพร้อมกับแต่ละองค์ประกอบของซึ่งช่วยให้หยุดก่อนได้Si


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

จุดที่ดี @KWillets! ขอบคุณสำหรับความคิดที่สวยงาม! ฉันรวมมันเป็นคำตอบของฉัน
DW

0

บางทีมันอาจดูเร็วกว่าอีกวิธีหนึ่ง ... นายกที่ใหญ่ที่สุดน้อยกว่าคือ 31607 รวมจำนวน 3401 ครั้งระหว่าง 2 และ 31607 ไม่ใช่จำนวนมาก เขียนตัวเลขแต่ละตัวที่คุณได้รับอย่างเต็มที่ในช่วงเวลาที่มีค่าสูงถึง 31607: นี่คือ 1 หรือนายกใหญ่ ดังนั้นเซตของนั้นค่อนข้างดีถ้าเวกเตอร์สอดคล้องกันนั้นมีความเป็นอิสระเป็นเส้นตรง (และ s นั้นต่างกันหรือทั้ง 1) และคุณกำลังมองหาอันดับของเมทริกซ์109

ai=p1ni1p2ni2Pi
PiainijP

การเชื่อมต่อกับความเป็นอิสระเชิงเส้นคืออะไร? เวกเตอร์และมีความเป็นอิสระเป็นเส้นตรง แต่ GCD คือในขณะที่เราต้องการ(0,0)(1,1)(1,0)(1,0)(0,0)
Yuval Filmus

1
ความเป็นอิสระเชิงเส้นดูเหมือนจะไม่ทำงาน แต่เราสามารถใช้การสลายตัวที่สำคัญในวิธีอื่น สำหรับแต่ละนายก (ใน 'และที่มากที่สุด ' s), กำหนดชุดเป็นชุดของตัวเลขทั้งหมด (ในชุดกำหนด) ซึ่งไม่ได้มีเป็นปัจจัย ปัญหาที่เกิดขึ้นในขณะนี้คือการหาส่วนย่อยที่เล็กที่สุดของตัวเลขดังกล่าวว่าสำหรับแต่ละ ,1 นี่เป็นปัญหาชุดการกดปุ่มซึ่งเท่ากับปัญหาการตั้งค่า นี่คือสมบูรณ์ แต่อาจมีการใช้งานบางอย่างเร็วพอสำหรับขนาดนี้ p3401 pi500 PiAppBAp|ApB|1NP
polkjh

คุณช่วยชี้แนะฉันไปยังการใช้งานบางอย่างที่สามารถใช้งานได้? จนถึงตอนนี้ฉันสามารถหาอัลกอริทึมการประมาณเท่านั้น ขอบคุณ!
Wakaka

รายงานการสำรวจนี้พิจารณาทั้งแนวทางโดยประมาณและวิธีแก้ปัญหาที่แน่นอน และเมื่อตอบกลับความคิดเห็นโปรดเพิ่ม @ name-of-person ในความคิดเห็น มันจะส่งการแจ้งเตือนไปยังบุคคลนั้น มิฉะนั้นพวกเขาอาจไม่เคยรู้เกี่ยวกับความคิดเห็นของคุณ
polkjh

-1

หากคุณสามารถค้นหาชุดย่อยที่มี gcd (S) = 1 ได้ฉันสามารถลบองค์ประกอบที่ซ้ำซ้อนออกจากชุดย่อยได้จนกว่าจะเหลือเพียง 2 องค์ประกอบเท่านั้นซึ่งมี gcd (S) = 1 ด้วยเหตุนี้ฉันจึงสามารถเรียกร้องได้ว่า เซตย่อยจะมี 2 องค์ประกอบหรือจะไม่มีอยู่

ตอนนี้เราใช้การสอบถามซ้ำเพื่อแก้ปัญหานี้ ลองแบ่งอาร์เรย์ของตัวเลขออกเป็น 2 ส่วนส่วนหนึ่งที่มีองค์ประกอบ n-1 และอีกส่วนหนึ่งมี 1 องค์ประกอบ (องค์ประกอบสุดท้าย) ทั้งสองหมายเลขจะอยู่ในองค์ประกอบ n-1 แรกหรือองค์ประกอบหนึ่งจะมีจากส่วนที่ 1 จับคู่กับองค์ประกอบสุดท้าย ดังนั้นเราสามารถแก้ไขปัญหานี้ได้

T (n) = T (n-1) + O (n) เวลา ซึ่งหมายถึง T (n) = O (n ^ 2)


4
gcd(6,10,15)=1 1 คุณสามารถลบองค์ประกอบใดได้บ้าง
Rick Decker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.