Có thể giải quyết vấn đề này tương đối hiệu quả bằng cách tính toán tất cả các gcd cặp, loại bỏ trùng lặp và sau đó đệ quy. Đó là hành động loại bỏ các bản sao trước khi bạn tái diễn làm cho nó hiệu quả.
Tôi sẽ giải thích thuật toán chi tiết hơn dưới đây, nhưng trước tiên, nó giúp xác định toán tử nhị phân . Nếu là tập hợp các số nguyên dương, hãy xác địnhS , T⊗S,T
S⊗T={gcd(s,t):s∈S,t∈T}.
Lưu ý rằngvà (trong vấn đề của bạn); thông thường, thậm chí sẽ nhỏ hơn một trong hai giới hạn đó, giúp thuật toán hoạt động hiệu quả. Cũng lưu ý rằng chúng ta có thể tính vớihoạt động gcd bằng cách liệt kê đơn giản.| S ⊗ T | ≤ 10 9 S ⊗ T S ⊗ T | S | × | T ||S⊗T|≤|S|×|T||S⊗T|≤109S⊗TS⊗T|S|×|T|
Với ký hiệu đó, đây là thuật toán. Đặt là tập hợp số đầu vào. Tính , sau đó , sau đó , v.v. Tìm nhỏ nhất sao cho nhưng . Sau đó, bạn biết rằng kích thước của tập hợp con nhỏ nhất là . Nếu bạn cũng muốn đưa ra một ví dụ cụ thể về một tập hợp con như vậy, bằng cách giữ các con trỏ ngược, bạn có thể dễ dàng xây dựng lại một tập hợp như vậy.S 2 = S 1 ⊗ S 1 S 3 = S 1 ⊗ S 2 S 4 = S 1 ⊗ S 3S1S2=S1⊗S1S3=S1⊗S2S4=S1⊗S31 ∈ S k 1 ∉ S k - 1 kk1∈Sk1∉Sk−1k
Điều này sẽ tương đối hiệu quả, vì không có bộ trung gian nào tăng kích thước trên (thực tế, kích thước của chúng có thể sẽ nhỏ hơn nhiều) và thời gian chạy cần khoảng hoạt động gcd. 500 × ( | S 1 | + | S 2 | + ⋯ )109500×(|S1|+|S2|+⋯)
Đây là một tối ưu hóa có thể cải thiện hiệu quả hơn nữa. Về cơ bản, bạn có thể sử dụng phép nhân đôi để tìm nhỏ nhất sao cho 1 ∈ S k . Cụ thể, với mỗi phần tử x ∈ S i , chúng tôi theo dõi tập hợp con nhỏ nhất của S 1 có gcd là và có kích thước là . (Khi bạn loại bỏ trùng lặp, bạn giải quyết các mối quan hệ có lợi cho tập hợp con nhỏ hơn.) Bây giờ, thay vì tính toán chuỗi chín bộ , chúng tôi thay vào đó sẽ tính toán chuỗi năm bộ , bằng máy tínhk1∈Skx∈SiS1≤ i S 1 , S 2 , S 3 , S 4 , ... , S 9 S 1 , S 2 , S 4 , S 8 , S 9 S 2 = S 1 ⊗ S 1 S 4 = S 2 ⊗ S 2 S 8 = S 4 ⊗ S 4 S 9 = Sx≤iS1,S2,S3,S4,…,S9S1,S2,S4,S8,S9S2=S1⊗S1 , sau đó , sau đó , sau đó . Khi bạn đi, tìm đầu tiên sao cho . Khi bạn đã tìm thấy sao cho , bạn có thể dừng ngay lập tức: bạn có thể tìm tập hợp con nhỏ nhất có gcd bằng bằng cách xem tập hợp con được liên kết với . Vì vậy, bạn có thể dừng ngay khi bạn đạt được một được đặt sao cho , cho phép bạn dừng sớm nếu bạn tìm thấy một tập hợp con nhỏ hơn.S4=S2⊗S2S8=S4⊗S4 k ∈ [ 1 , 2 , 4 , 8 , 9 ] 1 ∈ S k k 1 ∈ S k 1 1 S k 1 ∈ S kS9=S1×S8k∈[1,2,4,8,9]1∈Skk1∈Sk11Sk1∈Sk
Điều này nên được tiết kiệm thời gian và không gian hiệu quả. Để tiết kiệm dung lượng, đối với mỗi phần tử , bạn không cần lưu trữ toàn bộ tập hợp: đủ để lưu trữ hai điểm lùi (vì vậy hai phần tử của mà bạn đã lấy gcd của, để lấy ) và tùy chọn kích thước của tập hợp con tương ứng.S i , S j xx∈SkSi,Sjx
Về nguyên tắc, bạn có thể thay thế chuỗi bằng bất kỳ chuỗi bổ sung nào khác . Tôi không biết liệu một số chuỗi bổ sung khác sẽ tốt hơn không. Sự lựa chọn tối ưu có thể phụ thuộc vào việc phân phối các câu trả lời đúng và kích thước dự kiến của các bộ , điều này không rõ ràng đối với tôi, nhưng có lẽ có thể được rút ra theo kinh nghiệm thông qua thử nghiệm.S k[1,2,4,8,9]Sk
Tín dụng: Tôi cảm ơn KWillets về ý tưởng lưu trữ một tập hợp con số cùng với mỗi phần tử của , cho phép dừng sớm.Si