Anda memiliki tongkat panjang yang sewenang-wenang, tidak harus integral.
Dengan memotong beberapa batang (satu potong memotong satu batang, tetapi kita dapat memotong sesering yang kita inginkan), Anda ingin mendapatkan batang sedemikian rupa sehingga:
- Semua tongkat ini memiliki panjang yang sama;
- Semua tongkat setidaknya sepanjang tongkat lainnya.
Perhatikan bahwa kita mendapatkan stick setelah melakukan pemotongan
Algoritma apa yang akan Anda gunakan sehingga jumlah pemotongan yang diperlukan minimal? Dan berapa angka itu?
Sebagai contoh, ambil dan . Algoritme berikut dapat digunakan:
- Pesan tongkat dengan urutan panjang sedemikian rupa sehingga .
- Jika maka potong stick # 1 menjadi dua bagian yang sama. Sekarang ada dua batang dengan panjang , yang setidaknya sepanjang tongkat yang tersisa .
- Kalau tidak ( ), potong stick # 1 menjadi dua potongan ukuran yang tidak sama dan . Sekarang ada dua batang dengan panjang , yang lebih panjang dari dan batang lainnya .
Dalam kedua kasus, satu potongan sudah cukup.
Saya mencoba untuk menggeneralisasi ini ke lebih besar , tetapi tampaknya ada banyak kasus untuk dipertimbangkan. Bisakah Anda menemukan solusi yang elegan?
sumber
Seperti yang disarankan @randomA, kami akan melanjutkan dalam dua tahap: Pertama-tama kami menemukan set tongkat yang akan dipotong dan kemudian meminimalkan jumlah potongan.
Seperti dalam kasus khusus dalam pertanyaan, kami mengurutkan / memberi nama tongkat sehingga . Ini membutuhkan waktu O ( n log n ) .L.1≥ L2≥ ⋯ ≥ Ln O(nlogn)
Seperti yang ditunjukkan oleh @ user1990169, kita tidak perlu memotong sepotong .i≥k
Pada fase pertama kami menggunakan pencarian biner untuk menemukan angka , 1 ≤ s ≤ k , sehingga tongkat 1 , ... , s dapat dipotong menjadi setidaknya k keping ukuran L s (ditambah beberapa keping yang lebih kecil), tetapi tongkat 1 , … , s - 1 tidak dapat dipotong menjadi k potong berukuran L s - 1 . Ini akan membutuhkan waktu O ( k log k ) .s 1≤s≤k 1,…,s k Ls 1,…,s−1 k Ls−1 O(klogk)
Jika , nilai ini adalah ukuran optimal dan kita dapat melewati fase dua.Ls−1=Ls
Jika tidak kita tahu bahwa ukuran optimal memenuhi L s - 1 > o ≥ L s dan jika o > L s kemudian o hasil dari pemotongan setidaknya satu dari tongkat-potong berukuran sama. Fase dua akan menentukan o :o Ls−1>o≥Ls o>Ls o o
Untuk setiap tongkat , 1 ≤ i ≤ s , menentukan satu set ukuran kandidat sebagai berikut: Jika memotong menjadi potongan-potongan ukuran L s bergantian tongkat ke dalam r i buah (termasuk yang lebih pendek, jika ada), maka calon ini tongkat adalah semua nilai L ii 1≤i≤s Ls ri , di manaj≤ridanLiLij j≤ri . (Lihatjawaban @ user1990169untuk alasan mengapa ini adalah satu-satunya ukuran kandidat.)Lij<Ls−1
Pertahankan untuk setiap ukuran kandidat, seberapa sering hal itu terjadi. Menggunakan pohon pencarian yang seimbang, ini dapat dilakukan di , karena jumlah total ukuran calon terikat oleh Σ i r i ≤ 2 k .O(klogk) ∑iri≤2k
Sekarang ukuran kandidat yang paling sering terjadi dan mengarah ke pemotongan yang valid adalah yang memberikan kita solusi optimal. Selain itu, jika ada ukuran kandidat yang mengarah ke pemotongan yang valid, ukuran yang lebih kecil akan mengarah ke pemotongan yang valid juga.
Jadi kita dapat lagi menggunakan pencarian biner untuk menemukan panjang kandidat terbesar yang mengarah ke pemotongan valid . Kemudian kita beralih pada kumpulan panjang kandidat hingga ambang ini dan menemukan satu dengan banyak terbesar di antara mereka di O ( k ) .O(klogk) O(k)
Secara total kita mendapatkan runtime di , atau O ( k log k ) , jika kita mengabaikan (atau tidak harus melakukan) jenis awal.O(nlogn) O(klogk)
sumber
Setelah Anda telah memerintahkan tongkat dalam urutan panjang mereka, maka tongkat harus dipotong hanya jika semua tongkat L 1 , L 2 , . . . L i - 1 telah terpotong.Li L1,L2,...Li−1
Sekarang karena , kita tidak akan membuat potongan pada tongkat L k dan seterusnya, karena kita selalu dapat memiliki tongkat k dengan panjang L k .k<n Lk k Lk
Jadi sekarang alih-alih , kita hanya berurusan dengan tongkat k - 1 (mungkin menambahkan tongkat k -th secara keseluruhan), dan jumlah pemotongan maksimum yang diperlukan dalam kasus terburuk = k - 1 .n k−1 k =k−1
Juga, jika jumlah pemotongan optimal adalah , maka harus ada setidaknya satu set stik di antara stik k - 1 yang akan diambil secara keseluruhan dari 1 stik asli<k−1 k−1 (baik dalam bagian atau dalam 1 potong) , yaitu, tidak ada bagian dari tongkat asli yang akan dibiarkan 'tidak terambil'. Ini karena, berdasarkan prinsip lubang-merpati , harus ada setidaknya 1 potongan yang harus menghasilkan lebih dari 1 batang yang valid.
Anda kemudian dapat melakukan dua bersarang untuk loop (keduanya hingga ). Loop luar akan menunjukkan jumlah tongkat saya yang semua bagian harus diambil dan loop batin akan menunjukkan jumlah bagian j terbuat dari tongkat itu. Untuk setiap ukuran L ik i j Lij L1
memeriksa apakah Anda bisa mendapatkan tongkat k yang layak dengan memotong tongkatL1dan seterusnya secara berurutan, dan jika Anda bisa, maka perbarui pemotongan minimum yang diperlukan sejauh ini jika jumlah yang dibutuhkan saat ini kurang.
Total kompleksitas algoritma di atas adalahO(nlog(n)+k3)
sumber
Ide tingkat tinggi adalah pencarian biner.
Ukuran masing-masing tongkat k yang diminta akan menjadi setidaknya tongkat terkecil dan paling besar yang terbesar. Karena itu, kami melanjutkan dengan menggunakan pencarian biner pada ukuran tongkat tengah, lihat nomor dapat kita peroleh, jika k ′ ini lebih dari yang diberikan k maka kita tahu bahwa kita perlu memilih ukuran kandidat referensi baru. Jadi kami pindah ke tongkat referensi baru yang lebih besar atau lebih kecil. Kita berhenti ketika k ′ kurang dari kk′ k′ k k′ k
Setelah kami menemukan tongkat referensi yang sesuai, ada tempat sudut di mana kami perlu memperbaiki ukuran lebih lanjut. Kita dapat mengurutkan semua potongan tongkat dengan jumlah potongan pada mereka dan ukuran tongkat. Pilih satu dengan jumlah pemotongan paling sedikit dan ukuran paling sedikit. Kurangi jumlah potongan pada stick ini sebanyak 1 dan buat semua sub-stick dengan ukuran yang sama. Ini akan menjadi ukuran referensi baru, periksa untuk melihat apakah ukuran baru ini dapat menyebabkan dapat diterima . Saya akui, saya tidak tahu bagaimana cara mengikat waktu berjalan dalam kasus ini.k′
Semoga saya bisa melihat sesuatu yang bermanfaat dari jawaban lain.
sumber