Saya memiliki satu set angka, dan ingin menghitung subset maksimum sehingga jumlah dari dua elemen itu tidak habis dibagi integer . Saya mencoba untuk memecahkan masalah ini, tetapi saya telah menemukan solusi kuadratik, yang bukan respons yang efisien. , di mana adalah jumlah elemen dan diberikan konstan. Apakah ada solusi yang lebih baik daripada kuadratik?
algorithms
efficiency
manduinca
sumber
sumber
Jawaban:
Memang ada algoritma waktu linear untuk ini. Anda hanya perlu menggunakan beberapa konsep teori bilangan dasar. Mengingat dua nomor dan , jumlah mereka adalah dibagi ke , hanya jika jumlah sisa mereka dibagi ke . Dengan kata lain,n1 n2 K K
Konsep kedua yang perlu Anda pertimbangkan adalah bahwa, jumlah dua angka adalah , hanya jika salah satu dari mereka benar-benar lebih kecil dari dan yang lainnya tidak kurang dari . Dengan kata lain,r1≠r2 K K/2 K/2
Konsep ketiga yang perlu Anda pertimbangkan adalah bahwa, jika jumlah dua angka adalah , keduanya menyimpang dari oleh yaitur1≠r2 K ⌈K/2⌉−1 k≤⌈K/2⌉
Jadi, untuk setiap dalam konsep ketiga, Anda perlu memasukkan atau dalam set solusi, tetapi tidak keduanya. Anda diizinkan untuk meletakkan salah satu angka yang sebenarnya dapat dibagi oleh dan jika genap, Anda dapat menambahkan hanya satu angka yang sisanya adalah .k r1 r2 K K K/2
Karena itu, berikut adalah algoritmenya.
Diberikan set , mari cari solusi setN={n1,n2,⋯,nN} S,
Algoritma ini cukup panjang, tetapi idenya sangat sederhana.
sumber
Pertimbangkan seperangkat S ukuran n yang berisi semua bilangan asli. Kita harus membentuk subset maksimal dari set ini. Kami menggunakan properti modulus dasar dan menambahkan beberapa pengurangan untuk menyelesaikan masalah. Semoga bermanfaat buat kalian semua.
Untuk dua bilangan asli N1 dan N2: (N1 + N2) mod (K) = (R1 + R2) mod (K) di mana R1 = N1modK dan R2 = N2% K. 1. Jika kita (N1 + N2) modK = 0 artinya (R1 + R2)% K = 0. 2. Itu berarti R1 + R2 harus sama dengan K, 2K, 3K .... 3. Tetapi R1 terletak antara 0 & K-1 dan begitu juga R2, yang berarti jumlah mereka tidak dapat melebihi K-1 + K-1 = 2 (K-1). 4. Dari 2 dan 3 kita dapat menyimpulkan bahwa R1 + R2 harus sama dengan K. 5. Selanjutnya jika R1 + R2 = K itu berarti keduanya harus sama dengan K / 2 (hanya mungkin jika K genap) atau salah satunya harus lebih rendah dari lantai [K / 2] dan satu lebih besar dari yang sama. 6. Misalkan R1 = T dan R2 = KT, jika kita mengambil angka N1 dari S yang sisanya adalah R1 dan angka apa pun N2 dari S yang sisanya adalah R2 maka jumlah mereka akan habis dibagi oleh K. Oleh karena itu, himpunan bagian Solusi dapat memiliki keduanya angka dengan sisa R1 atau yang dengan sisa R2 tetapi tidak keduanya.
Sekarang Misalkan kita membangun R array ukuran K dengan indeks 0 hingga K-1, Elemen dalam setiap indeks menunjukkan jumlah angka dalam himpunan S dengan sisa (pada pembagian dengan K) sama dengan nomor indeks. Kita tidak dapat memiliki lebih dari 2 angka dengan sisa 0 karena jumlahnya akan habis dibagi oleh K oleh karena itu kita harus menginisialisasi penghitung kita dengan min (R [0], 1). Untuk T = 1 hingga T
Kode untuk algoritma yang sama dalam C ++ adalah seperti yang ditunjukkan di bawah ini:
sumber
Saya mencoba menerjemahkan ke kode C #, yang pertama hanya menghitung ukuran array subset dan lainnya termasuk seluruh subset (hash).
Menghitung:
Dengan subset:
sumber