kadang-kadang ketika pemrograman berulang, Anda memanggil fungsi dengan parameter yang sama beberapa kali yang tidak diperlukan.
Contoh terkenal angka Fibonacci:
index: 1,2,3,4,5,6...
Fibonacci number: 1,1,2,3,5,8...
function F(n) {
if (n < 3)
return 1
else
return F(n-1) + F(n-2)
}
Mari kita jalankan F (5):
F(5) = F(4) + F(3)
= {F(3)+F(2)} + {F(2)+F(1)}
= {[F(2)+F(1)]+1} + {1+1}
= 1+1+1+1+1
Jadi kita telah memanggil: 1 kali F (4) 2 kali F (3) 3 kali F (2) 2 kali F (1)
Pendekatan Pemrograman Dinamis: jika Anda memanggil suatu fungsi dengan parameter yang sama lebih dari satu kali, simpan hasilnya ke dalam variabel untuk langsung mengaksesnya di lain waktu. Cara berulang:
if (n==1 || n==2)
return 1
else
f1=1, f2=1
for i=3 to n
f = f1 + f2
f1 = f2
f2 = f
Mari kita panggil F (5) lagi:
fibo1 = 1
fibo2 = 1
fibo3 = (fibo1 + fibo2) = 1 + 1 = 2
fibo4 = (fibo2 + fibo3) = 1 + 2 = 3
fibo5 = (fibo3 + fibo4) = 2 + 3 = 5
Seperti yang Anda lihat, kapan pun Anda membutuhkan panggilan ganda, Anda cukup mengakses variabel yang sesuai untuk mendapatkan nilai alih-alih menghitung ulang.
Omong-omong, pemrograman dinamis tidak berarti mengubah kode rekursif menjadi kode berulang. Anda juga dapat menyimpan subresult ke dalam variabel jika Anda menginginkan kode rekursif. Dalam hal ini teknik ini disebut memoisasi. Sebagai contoh kita terlihat seperti ini:
// declare and initialize a dictionary
var dict = new Dictionary<int,int>();
for i=1 to n
dict[i] = -1
function F(n) {
if (n < 3)
return 1
else
{
if (dict[n] == -1)
dict[n] = F(n-1) + F(n-2)
return dict[n]
}
}
Jadi hubungannya dengan Divide and Conquer adalah algoritma D&D mengandalkan rekursi. Dan beberapa versi dari mereka memiliki "panggilan fungsi ganda dengan masalah parameter yang sama." Cari "perkalian rantai matriks" dan "urutan umum terpanjang" untuk contoh-contoh semacam itu di mana DP diperlukan untuk meningkatkan T (n) dari D&D juga.