Pemrograman dinamis memberi Anda cara untuk berpikir tentang desain algoritma. Ini seringkali sangat membantu.
Metode memoo dan bottom-up memberi Anda aturan / metode untuk mengubah hubungan perulangan menjadi kode. Memoisasi adalah ide yang relatif sederhana, tetapi sering kali ide terbaik adalah!
Pemrograman dinamis memberi Anda cara terstruktur untuk berpikir tentang waktu berjalan dari algoritma Anda. Waktu yang berjalan pada dasarnya ditentukan oleh dua angka: jumlah sub-masalah yang harus Anda selesaikan, dan waktu yang dibutuhkan untuk menyelesaikan setiap sub-masalah. Ini memberikan cara mudah yang mudah untuk memikirkan masalah desain algoritma. Ketika Anda memiliki relasi pengulangan kandidat, Anda dapat melihatnya dan dengan sangat cepat mengetahui waktu pelaksanaannya (misalnya, Anda seringkali dapat dengan cepat memberi tahu berapa banyak subproblem yang akan ada, yang merupakan batas bawah pada waktu berjalan; jika ada banyak masalah yang harus Anda selesaikan secara eksponensial, maka perulangan mungkin tidak akan menjadi pendekatan yang baik). Ini juga membantu Anda mengesampingkan dekomposisi kandidat subproblem. Misalnya, jika kita memiliki string urutan S tidak mungkin menjadi pendekatan yang baik (jumlah subproblem adalah eksponensial dalam n ). Ini memungkinkan Anda memangkas "ruang pencarian" dari kemungkinan perulangan. , mendefinisikan subproblem dengan awalan S [ 1 .. i ] atau suffix S [ j . . n ] atau substring S [ i . . j ] mungkin masuk akal (jumlah subproblem adalah polinomial dalam n ), tetapi mendefinisikan subproblem dengan urutan dariS[1..n]S[1..i]S[j..n]S[i..j]nSn
Pemrograman dinamis memberi Anda pendekatan terstruktur untuk mencari hubungan pengulangan kandidat. Secara empiris, pendekatan ini seringkali efektif. Secara khusus, ada beberapa heuristik / pola umum yang dapat Anda kenali untuk cara-cara umum untuk mendefinisikan subproblem, tergantung pada jenis input. Contohnya:
Jika input adalah bilangan bulat positif , salah satu cara kandidat untuk mendefinisikan subproblem adalah dengan mengganti n dengan integer yang lebih kecil n ′ (st 0 ≤ n ′nnn′ ).0 ≤ n′≤ n
Jika inputnya adalah string , beberapa kandidat cara untuk mendefinisikan subproblem meliputi: ganti S [ 1 .. n ] dengan awalan S [ 1 .. i ] ; ganti S [ 1 .. n ] dengan akhiran S [ j . . n ] ; ganti S [ 1 .. n ] dengan substring S [ i . (Di sini subproblem ditentukan oleh pilihan i ,S[ 1 .. n ]S[ 1 .. n ]S[ 1 .. i ]S[ 1 .. n ]S[ j . . n ]S[1..n]S[i..j]i,j .)
Jika input adalah daftar , lakukan hal yang sama seperti yang Anda lakukan untuk string.
Jika inputnya adalah pohon , salah satu cara kandidat untuk mendefinisikan subproblem adalah mengganti T dengan subtree T (yaitu, pilih node x dan ganti T dengan subtree yang di-root pada x ; subproblem ditentukan oleh pilihan x ).TTTxTxx
Jika inputnya adalah sepasang , maka secara rekursif lihatlah tipe x dan tipe y untuk mengidentifikasi cara untuk memilih subproblem untuk masing-masing. Dengan kata lain, satu kandidat cara untuk mendefinisikan subproblem adalah mengganti ( x , y ) dengan ( x ′ , y ′ ) di mana x ′ adalah subproblem untuk x dan y ′ adalah subproblem untuk y . (Anda juga dapat mempertimbangkan submasalah formulir(x,y)xy(x,y)(x′,y′)x′xy′y Atau ( x ′ , y ) .)(x,y′)(x′,y)
Dan seterusnya. Ini memberi Anda heuristik yang sangat berguna: hanya dengan melihat tipe tanda tangan dari metode ini, Anda dapat menemukan daftar cara kandidat untuk mendefinisikan subproblem. Dengan kata lain, hanya dengan melihat pernyataan masalah - hanya melihat jenis input - Anda dapat menemukan beberapa kandidat cara untuk mendefinisikan subproblem.
Ini seringkali sangat membantu. Itu tidak memberi tahu Anda apa hubungan perulangan itu, tetapi ketika Anda memiliki pilihan tertentu untuk bagaimana mendefinisikan subproblem, seringkali tidak terlalu sulit untuk menentukan hubungan perulangan yang sesuai. Jadi, sering kali mengubah desain algoritma pemrograman dinamis menjadi pengalaman terstruktur. Anda menuliskan pada kertas memo daftar kandidat cara untuk mendefinisikan subproblem (menggunakan heuristik di atas). Kemudian, untuk masing-masing kandidat, Anda mencoba untuk menulis hubungan pengulangan, dan mengevaluasi waktu berjalannya dengan menghitung jumlah sub-masalah dan waktu yang dihabiskan per sub-masalah. Setelah mencoba setiap kandidat, Anda menyimpan yang terbaik yang dapat Anda temukan. Menyediakan beberapa struktur untuk proses desain algoritma adalah bantuan besar, karena jika tidak, desain algoritma dapat mengintimidasi (ada '