Belon Meletup: DP Selang Songsang
Selesaikan masalah belon meletup dengan berfikir secara songsang — pilih belon terakhir yang diletupkan dalam setiap selang, bukannya belon pertama.
Belon Meletup: DP Selang Songsang ialah pelajaran Persediaan Temu Duga Pengaturcaraan percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Persediaan Temu Duga Pengaturcaraan, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.
Masalah Belon Meletup
Diberikan n belon dengan nilai nums, meletupkan belon i memperoleh nums[i-1] * nums[i] * nums[i+1] syiling (hasil darab belon itu sendiri dengan jiran semasanya). Selepas belon itu meletup, jiran-jirannya menjadi bersebelahan. Cari jumlah maksimum syiling yang boleh dikumpulkan dengan meletupkan semua belon. Simulasi naif sukar kerana tindakan meletup mengubah jiran — DP selang songsang mengatasi kesukaran ini dengan berkesan.
Mengapa Simulasi ke Hadapan Gagal
Jika kita cuba mentakrifkan dp[i][j] sebagai syiling maksimum daripada meletupkan belon dalam julat [i, j] dan memikirkan belon yang perlu diletupkan dahulu, kita menghadapi masalah: meletupkan belon k dahulu bermakna nums[k-1] dan nums[k+1] mestilah jiran semasa — tetapi belon-belon itu mungkin diletupkan kemudian, lalu mengubah jiran secara dinamik. Keadaan ini sukar ditakrifkan dengan kemas dalam arah ke hadapan.
Idea Utama: Fikirkan Secara Songsang
Helahnya ialah memikirkan belon yang menjadi belon terakhir untuk diletupkan dalam selang [i, j]. Apabila belon k ialah belon terakhir yang diletupkan dalam [i, j], semua belon lain dalam [i, j] sudah tiada. Jadi jiran belon k tepat-tepat ialah nums[i-1] dan nums[j+1] — belon sempadan yang berada di luar selang. Hal ini menjadikan pengiraan syiling bagi letupan terakhir tentu: pengiraan itu tidak bergantung pada susunan letupan terdahulu.
Takrif Keadaan dan Hubungan Rekursi
Tambahkan belon penanda: tambahkan 1 pada awal dan akhir nums untuk membentuk nums = [1] + nums + [1]. Takrifkan dp[i][j] sebagai syiling maksimum daripada meletupkan semua belon yang terletak tepat di antara indeks i dan j (tidak termasuk kedua-duanya), dengan nums[i] dan nums[j] sebagai belon sempadan yang masih kekal. Hubungan rekursi: bagi setiap calon belon terakhir k dalam (i, j): dp[i][j] = max(dp[i][k] + dp[k][j] + nums[i]*nums[k]*nums[j]).
# With sentinels: nums = [1] + original + [1]
# dp[i][j] = max coins from bursting all balloons in open interval (i, j)
# k = last balloon to burst in (i,j)
# dp[i][j] = max over k in (i,j): dp[i][k] + dp[k][j] + nums[i]*nums[k]*nums[j]Pelaksanaan Lengkap
Kita menambah belon penanda pada tatasusunan, memulakan jadual DP dengan sifar (selang kosong = 0 syiling), dan mengisinya mengikut panjang selang yang semakin meningkat. Jawapan akhir ialah dp[0][n+1], yang mewakili syiling maksimum daripada meletupkan semua belon asal dengan belon penanda sebagai sempadan kekal.
def maxCoins(nums):
nums = [1] + nums + [1]
n = len(nums)
dp = [[0]*n for _ in range(n)]
# length of open interval (i, j) exclusive: j - i - 1 balloons inside
for length in range(2, n): # length = j - i
for i in range(0, n - length):
j = i + length
for k in range(i+1, j): # k is last burst in (i, j)
coins = dp[i][k] + dp[k][j] + nums[i]*nums[k]*nums[j]
dp[i][j] = max(dp[i][j], coins)
return dp[0][n-1]
print(maxCoins([3, 1, 5, 8])) # 167Menelusuri Contoh
Bagi [3, 1, 5, 8], selepas ditambah belon penanda menjadi [1, 3, 1, 5, 8, 1] (indeks 0 hingga 5). Kita mahu dp[0][5]. Bagi selang panjang=2 (satu belon di dalamnya): dp[0][2] = 1*3*1=3, dp[1][3]=3*1*5=15, dp[2][4]=1*5*8=40, dp[3][5]=5*8*1=40. Dengan membina secara berperingkat, pilihan optimum ialah meletupkan 1 terakhir antara {3,1,5,8} selepas meletupkan jiran-jirannya terlebih dahulu, menghasilkan jumlah 167 syiling.
Analisis Kerumitan
Terdapat O(n²) selang dan bagi setiap selang kita mencuba O(n) titik pemisahan, lalu menghasilkan kerumitan masa O(n³). Ruang ialah O(n²) untuk jadual DP. Bagi n = 500 belon, ini bersamaan dengan 125 juta operasi — masih munasabah untuk kekangan temu duga. Penambahan belon penanda pada kedua-dua hujung memudahkan pengendalian sempadan: tanpanya, anda perlu membuat semakan khusus untuk menentukan sama ada i-1 dan j+1 berada dalam sempadan.
Alternatif Atas ke Bawah dengan Memoisasi
Penyelesaian yang sama boleh ditulis secara atas ke bawah dengan @lru_cache, yang mungkin lebih mudah diterbitkan semasa temu duga. Takrifkan solve(i, j) sebagai syiling maksimum dalam selang terbuka (i, j). Fungsi ini mencuba semua k sebagai belon terakhir yang diletupkan dan menyimpan hasilnya secara memoisasi. Kedua-dua pendekatan mempunyai kerumitan masa dan ruang yang sama.
from functools import lru_cache
def maxCoins_memo(nums):
nums = [1] + nums + [1]
n = len(nums)
@lru_cache(maxsize=None)
def solve(i, j):
if j - i < 2: # no balloons between i and j
return 0
return max(
solve(i, k) + solve(k, j) + nums[i]*nums[k]*nums[j]
for k in range(i+1, j)
)
return solve(0, n-1)
print(maxCoins_memo([3, 1, 5, 8])) # 167Kesilapan Biasa: Takrifan DP ke Hadapan
Satu kesilapan biasa ialah mentakrifkan dp[i][j] sebagai syiling apabila belon pertama dalam [i,j] diletupkan, bukannya belon terakhir. Pendekatan ini gagal kerana pengiraan syiling bagi letupan pertama bergantung pada belon jiran yang belum diletupkan — dan keadaan jiran tersebut berubah apabila algoritma berjalan. Sentiasa fikirkan elemen terakhir dalam DP selang apabila sempadan bergantung pada elemen yang masih ada.
Mengapa Nilai Penanda 1?
Penanda bernilai 1 dipilih kerana bertindak sebagai unsur neutral bagi pendaraban. Apabila belon sempadan menjadi belon terakhir yang diletupkan, nilai syilingnya ialah boundary * last * boundary = 1 * last * 1 = last. Menggunakan 0 akan memberikan 0 syiling (salah), manakala nilai lain akan memesongkan pengiraan. Helah penanda menyatukan semua kes sempadan dengan kemas tanpa memerlukan pengendalian khusus untuk belon paling kiri dan paling kanan.
Perbandingan dengan DP Selang Standard
Dalam DP selang standard (pendaraban rantaian matriks), titik pemisahan k mewakili tempat kita membahagikan masalah kepada dua submasalah yang diselesaikan secara bebas. Dalam Masalah Belon Meletup, k ialah belon yang diletupkan terakhir dalam selang, lalu menjadikan dua subselang [i,k] dan [k,j] tidak bersandar antara satu sama lain apabila k masih wujud sebagai sempadan. Perspektif songsang ini ialah idea kreatif yang menjadikan masalah belon meletup boleh diselesaikan dengan DP selang.
Semakan Ringkas
Uji pemahaman anda tentang konsep Struktur Data & Algoritma — Persediaan Temu Duga Pengekodan daripada pelajaran ini.
Rumusan Pelajaran
Dalam pelajaran ini, anda telah mempelajari: simulasi ke hadapan gagal kerana pemecahan belon mengubah jiran secara tidak dapat diramalkan, pemerhatian songsang mentakrifkan k sebagai belon terakhir yang dipecahkan dalam suatu selang, menjadikan jiran sebagai nums[i] dan nums[j], dan hubungan dp[i][j] = max(dp[i][k] + dp[k][j] + nums[i]*nums[k]*nums[j]) dengan penambahan nilai penanda memberikan penyelesaian O(n³). Seterusnya, kita beralih kepada DP beg galas, bermula dengan beg galas 0/1 klasik dan pengoptimuman ruangnya.
Pelajari Persediaan Temu Duga Pengaturcaraan dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 90
- Pelajaran
- 360
Soalan Lazim
Adakah pelajaran “Belon Meletup: DP Selang Songsang” percuma?
Ya — teks penuh “Belon Meletup: DP Selang Songsang” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Persediaan Temu Duga Pengaturcaraan, tingkat taraf kepada CoddyKit PRO. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Belon Meletup: DP Selang Songsang”?
Selesaikan masalah belon meletup dengan berfikir secara songsang — pilih belon terakhir yang diletupkan dalam setiap selang, bukannya belon pertama. Anda berlatih Persediaan Temu Duga Pengaturcaraan menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Persediaan Temu Duga Pengaturcaraan?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Persediaan Temu Duga Pengaturcaraan di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.
Berapa lamakah pelajaran “Belon Meletup: DP Selang Songsang” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Persediaan Temu Duga Pengaturcaraan ini?
Ya. Setiap pelajaran Persediaan Temu Duga Pengaturcaraan menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Corak DP Selang dan Susunan Pengisian
- Subjujukan dan Subrentetan Palindrom Terpanjang
- Pembahagian Palindrom II
- Belon Meletup: DP Selang Songsang