You are on page 1of 50

Kỹ thuật lập trình

Programming Techniques
Ts. Nguyễn Đức Thuần
BM Hệ thống Thông Tin
Giới thiệu môn học

Nội dung môn hoc

 Chương 1: Kỹ thuật tổ chức chương trình


 Chương 2: Lập trình có cấu trúc – Hàm nâng cao
 Chương 3: Đệ qui
 Chương 4: Thử sai quay lui – Nhánh cận
 Chương 5: Chia để trị
 Chương 6: Tham lam
 Chương 7: Qui hoạch động

Page  2
QUI HOẠCH ĐỘNG
(Dynamic Programming)

Page  3
Chương 7: QUI HOẠCH ĐỘNG

I. NỘI DUNG
 Giới thiệu
 Phương pháp
 Các ví dụ
 Ưu điểm và khuyết điểm

Page  4
Chương 7: QUI HOẠCH ĐỘNG

I. GIỚI THIỆU

R.E. Bellman đề xuất vào những năm 50

- Là một phương pháp toán học nghiên cứu xử


lý các bài toán đa tầng, trong đó có những bài
toán con được lặp lại.

- Tên Qui hoach động ~ Lập kế hoạch theo


thời gian

(để tránh giới lãnh đạo không thích Toán học!).

Richard Ernest Bellman


1920 - 1984

Page  5
Chương 7: QUI HOẠCH ĐỘNG

• Quy hoạch động là một phương pháp giảm thời gian chạy của các thuật
toán có các bài toán con trùng lắp (overlapping subproblem) và cấu trúc
con tối ưu (optimal substructure).
• Quy hoạch động sẽ giải một bài toán con một lần và lời giải của các bài
toán con sẽ được lưu giữ lại nhằm khỏi
giải lại các bài toán con.
• Quy hoạch động là quá trình tiếp cận thuật toán theo quá trình từ dưới
lên (bottom-up).

Chú ý:
 Kỹ thuật Chia để trị, thường phân bài toán đã cho thành các bài
toán độc lập.

Page  6
Chương 7: QUI HOẠCH ĐỘNG

II. PHƯƠNG PHÁP


CÁC BƯỚC LẬP TRÌNH QUI HOẠCH ĐỘNG
1. Phân rã bài toán đã cho thành các bài toán con. Tìm không gian nhớ
phù hợp để lưu trữ nghiệm các bài toán con (*): (Table)/hoặc bộ nhớ
(Memoization).
2. Giải các bài toán con nhỏ nhất (bài toán cơ sở) lưu vào (*).
3. Kết hợp các bài toán cơ sở đưa ra lời giải của bài toán lớn hơn.
4. Căn cứ vào (*) đưa ra lời giải cho bài toán tổng quát (Truy vết của qui
hoạch động)
Chú ý:
Trong qui hoạch động, khi giải quyết nhiều bài toán con và lưu trữ kết
quả: không phải tất cả chúng sẽ góp phần giải quyết bài toán lớn hơn.
Do cấu trúc tối ưu, có thể chắc chắn rằng ít nhất một số các bài toán con
sẽ hữu ích.
Page  7
Chương 7: QUI HOẠCH ĐỘNG

Có hai tính chất quan trọng mà một bài toán tối ưu cần phải thoả mãn để có
thể áp dụng quy hoạch động để giải nó là:
1. Cấu trúc con tối ưu: Để giải được bài toán đặt ra một cách tối ưu,
mỗi bài toán con cũng phải được giải một cách tối ưu.
2. Số lượng các bài toán con phải không quá lớn: Rất nhiều các
bài toán có thể giải được nhờ quy hoạch động, nhưng việc làm này
là không hiệu quả do số lượng các bài toán con tăng theo hàm mũ.
Một đòi hỏi quan trọng đối với quy hoạch động là tổng số các bài
toán con cần giải là không quá lớn, cùng lắm phải bị chặn bởi một
đa thức của kích thước dữ liệu vào.
Lập bảng
+ cài đặt

Page  8
Chương 7: QUI HOẠCH ĐỘNG

Sự khác biệt giữa Qui hoạch động & Chia để trị


Quy hoạch động Chia để trị
Bottom-up Top-down
Dùng bảng để lưu kết quả  các Thường dùng đệ quy  các bài
bài toán con chỉ giải duy nhất 1 lần toán con có thể giải đi giải lại nhiều
lần
Thường dùng cho các bài toán tối Thường dùng cho các bài toán chỉ
ưu, tìm lời giải tốt nhất trong các có một lời giải duy nhất
lời giải
Phân rã thành các bài toán con có Phân rã thành các bài toán con
cấp nhỏ hơn  việc giải bài toán cùng cấp  việc giải các bài toán
cấp n hoàn toàn phụ thuộc vào kết con đôi khi không liên quan đến
quả của bài toán cấp n-1 nhau
Độ phức tạp nhỏ nhờ sử dụng Độ phức tạp thời gian lớn nếu có
bảng quy hoạch để nhớ kết quả nhiều bài toán con giống nhau
Page  9
Chương 7: QUI HOẠCH ĐỘNG

III. MỘT SỐ BÀI TOÁN ĐIỂN HÌNH


1. Phần tử thứ n của dãy số Fibonacci

Cách 1: Lập trình đệ qui: (không qui hoạch động)

Page  10
Chương 7: QUI HOẠCH ĐỘNG

Cách 2: Dùng 3 biến a, b, c

Chú ý: Đây là phương pháp lập trình qui hoạch động dùng bộ nhớ để lưu
kết quả trung gian (Memoization)

Page  11
Chương 7: QUI HOẠCH ĐỘNG

Cách 3: Lập trình qui hoạch động, dùng Table để lưu trữ
B1: Dùng 1 mảng lưu trữ F[i], i=1,n
B2: Cơ sở: F[1]=1; F[2]=1;
B3: Truy hồi F[i]=F[i-1]+F[i-2];
B4: F[n] kết quả.

Page  12
Chương 7: QUI HOẠCH ĐỘNG

Page  13
Chương 7: QUI HOẠCH ĐỘNG

// Hàm lũy thừa bậc n của F[2][2]

B4: Truy vết tìm nghiệm:

Page  14
Chương 7: QUI HOẠCH ĐỘNG

2. Biểu diễn số thành tổng các ký số cho trước


Cho n là một số tự nhiên. Hãy tìm số cách khác nhau để biểu diễn n là
tổng của các số 1, 3, 4.
Ví dụ: Input n = 5; Output: 6
n=5
n= 1+1+1+1+1
1+1+3
1+3+1
3+1+1
1+4
4+1

Định nghĩa các bài toán con như thế nào ?

Page  15
Chương 7: QUI HOẠCH ĐỘNG
Làm sao có công thức
Truy hồi đó hè?
 Định nghĩa các bài toán con:
Dn là số cách viết n thành tổng các số 1, 3, 4
• Tìm thấy công thức truy hồi
Dn=Dn-1+Dn-3+Dn-4 với n>4
B1: Dùng mảng 1 chiều để lưu trữ
Biểu diễn:
B2: Cơ sở: (Giá trị ban đầu:) D1=1; D2=1; D3=2; D4=4
N=x1+x2+..+xn
B3: Truy hồi:  Nếu buộc số hạng cuối là 1,
Thì có Dn-1 cách khác nhau.

 Nếu buộc số hạng cuối là 3,


Thì có Dn-3 cách khác nhau.

 Nếu buộc số hạng cuối là 4,


Thì có Dn-4 cách khác nhau.

Cách biểu diễn n thành tổng


Chú ý: Mỗi phần tử chỉ tính 1 lần. Các số 1, 3, 4 chỉ có 4 trường
hợp đó xảy ra , vì vậy ta có
Công thức truy hồi!
B4: D[n] là kết quả cần tìm.
Page  16
Chương 7: QUI HOẠCH ĐỘNG

Page  17
Chương 7: QUI HOẠCH ĐỘNG

• Dùng mảng 1 chiều c[k]


• Để ý:
• Lần 0: 0 1 2 3 .. .. .. k
1  0 0 0 0

• Lần 1: 0 1 2 3 .. .. .. k
1  1  0 0 0

• Lần 2: 0 1 2 3 .. .. .. k
1 2 1 0 0

• ….

Page  18
Chương 7: QUI HOẠCH ĐỘNG

4. Dãy con có tổng bằng P: Cho một dãy k các số nguyên, và một số S.
Hỏi tồn tại một dãy con của dãy đã cho có tổng bằng S? Nếu có liệt kê?
Thử làm bài đổi tiền xem
- Input: {0,10,8,7,6,6,6,6}; S=25;
- Output: Có dãy con 7 8 10
B1: Dùng mảng 2 chiều P[n][n] để lưu giữ trạng thái (n=max(k,S)) với
P[i][j] = 1 nếu có một dãy con từ a[1] đến a[i] có tổng bằng j, (ngược lại =
0)
Nhận xét: P[i][0]=1; P[0][i]=0;
P[i-1][j] = 1  P[i][j] =1
P[i-1][j-a[i]]=1  P[i][j] =1
B2: Cơ sở: P[i][0]=1; P[0][i]=0;
B3: Truy hồi: for(i=1;i<=n;i++) for(j=1;j<=S;j++)
if ((P[i-1][j]==1)||(P[i-1][j-a[i]]==1)) P[i][j]=1;
Page  19
Chương 7: QUI HOẠCH ĐỘNG

B4: Truy vết:


- Nếu P[n][S] = 1  Tồn tại dãy con có tổng bằng S;
- In ra dãy con:
Nếu (P[i][S]==1)&&(P[i-1][S]==0)  a[i] có tham gia vào dãy con

Page  20
Chương 7: QUI HOẠCH ĐỘNG

Luyện tập: Thử nêu cách giải bài toán chia kẹo:
Có N gói kẹo, gói thứ i có A[i] cái kẹo. Yêu cầu: Hãy tìm cách chia các gói
kẹo này thành 2 phần sao cho độ chênh lệch giữa tổng số kẹo ở hai phần
là ít nhất có thể được 0 <1000, 2<=N<=10000

Bài tập (bắt buộc)!


Page  21
Chương 7: QUI HOẠCH ĐỘNG

5. Chia n phần thưởng cho m học sinh.


Cần chia hết n phần thưởng cho m học sinh sắp theo thứ tự giảm dần
Điểm trung bình, sao cho mỗi bạn nhận được phần thưởng không ít hơn
phần thưởng của bạn xếp sau mình (có thể số phần thưởng = 0),
1<=m,n<= 70. Tính số cách chia phần thưởng
Ví dụ: Chia 7 phần thưởng
cho 4 học sinh, có 11 cách
chia.

Page  22
Chương 7: QUI HOẠCH ĐỘNG

Cách 1: Lập trình đệ qui (không qui hoạch động)


Đặt Chia(i, j) là số cách chia I phần thưởng cho j học sinh:
1. Nếu j=0: Chia(i, j)=0; // Không có hs không có cách chia
2. Nếu i=0: Chia(0, j)=1;// Mỗi hs được 0 phần thưởng
Qui ước Chia(0,0) = 1;
3. Nếu i <j: Chia(i, j) = Chia(i, i);
4. Nếu i>=j: Có 2 trường hợp:
 Học sinh thứ j không nhận phần thưởng: Chia(i, j) = Chia (i, j-1)
 Học sinh thứ j có nhận phần thưởng: Chia(i, j)= Chia(i-j, j);
Tổng hợp:
Chia (i, j) = Chia(i, j-1) + Chia(i-j, j);
(Lập trình như bài tập!)
Page  23
Chương 7: QUI HOẠCH ĐỘNG

// Hàm đệ qui

Page  24
Chương 7: QUI HOẠCH ĐỘNG

Cách 2: (Lập trình qui hoạch động)


 Phương án 1: Dùng mảng 2 chiều để lưu kết quả trung gian
c[0][i] = 1; c[0][0]=1; c[i][0] = 0;
c[i][j] = c[i][i] , nếu i<j;
c[i][j] = c[i-j][j] + c[i][j-1], nếu ij;
Giá trị trả về: c[n] [m]
B1: Dùng mảng lưu trữ
B2: Cơ sở: c[0][i] = 1; c[0][0]=1; c[i][0] = 0;
c[i][j] = c[i][i] , nếu i<j;
B3: Truy hồi: c[i][j] = c[i-j][j] + c[i][j-1], nếu ij;
B4: Kết quả c[n][m]
(Lập trình)
Page  25
Chương 7: QUI HOẠCH ĐỘNG

Cách 2: (Lập trình qui hoạch động)


 Phương án 2: Dùng mảng 1 chiều để lưu kết quả trung gian
 Dùng mảng hai chiều chúng ta chỉ có thể tính toán được với dữ liệu
nhỏ. Quan sát kĩ quy trình gán trị cho mảng hai chiều theo từng cột
- cột thứ j có thể được tính toán từ cột thứ j - 1. Nếu gọi c là mảng một
chiều sẽ dùng, ta cho số học sinh tăng dần bằng cách lần lượt tính j
bước, với j := 1..n. Tại bước thứ j, c[i] chính là số cách chia i phần
thưởng cho j học sinh.
- Như vậy, tại bước thứ j ta có:
c[i] (tại bước j) = c[i] tại bước (j – 1), nếu i < j. Từ đây suy ra:
đoạn c[0..(j – 1)] được bảo lưu.
- c[i] (tại bước j) = c[i] (tại bước (j – 1)) + c[i – j] (tại bước j), nếu i j.
Biểu thức thứ hai cho biết khi cập nhật mảng c từ bước thứ j – 1 qua
bước thứ j ta phải tính từ trên xuống, nghĩa là tính dần theo chiều tăng
của i = j..m.
Page  26
Chương 7: QUI HOẠCH ĐỘNG

Cách 2: (Lập trình qui hoạch động)


 Phương án 2: Dùng mảng 1 chiều để lưu kết quả trung gian

 Chú ý: Bài tập còn có thể phát biểu: Hãy tính số cách biểu diễn số
tự nhiên n thành tổng của m số tự nhiên sắp theo trật tự không tăng.
Thí dụ, với n = 7, m = 4 ta có:
7 = 7 + 0 + 0 + 0 = 6 + 1 + 0 + 0 ….

Page  27
Chương 7: QUI HOẠCH ĐỘNG

6. Tìm dãy con đơn điệu dài nhất Cho a là một dãy có n phần tử
a1,a2,..,an. Một dãy con của a là dãy ai1,ai2,..aik với i1<i2<..<ik
Tìm dãy con của a, đơn điệu tăng dài nhất.
Ví dụ:
1 2 3 4 5 6 7 8 9 10
5 2 3 4 9 10 5 6 7 8

B1: Khai báo mảng: a [0..n+1] lưu trữ các phần tử đã cho
L[0..n+1] lưu trữ độ dài các dãy con tăng dần
cụ thể L[i] là độ dài dãy con đơn điệu tăng dần kể từ a[i]
Gán a[0]=-; a[n+1]=+
B2: Cơ sở: L[n+1] =1

Page  28
Chương 7: QUI HOẠCH ĐỘNG

B3: Công thức truy hồi:


L[i] là lớn nhất, khi a[i] được ghép với dãy con tăng dần dài nhất kể từ vị
trí thứ j (j>I và a[j]>a[i])
L[i] = max L[j] +1
i<j<=n+1
a[j]>a[i]

i 0 1 2 3 4 5 6 7 8 9 10 11
a - 5 2 3 4 9 10 5 6 7 8 +
L 9 5 8 7 6 3 2 5 4 3 2 1

Để in ra dãy con dài nhất, dùng một mảng T[0..n+1]:


T[i] = j, với j là chỉ số bé nhất sao cho a[i], a[j] thuộc cùng dãy con đơn
điệu tăng dài nhất.

Page  29
Chương 7: QUI HOẠCH ĐỘNG

i 0 1 2 3 4 5 6 7 8 9 10 11
a - 5 2 3 4 9 10 5 6 7 8 +
L 9 5 8 7 6 3 2 5 4 3 2 1
T 2 8 3 4 7 6 11 8 9 10 11

T[i] = jmax nếu L[i] = L[jmax] +1

B4: Truy vết:


 Chiều dài dãy con đơn điệu tăng dài nhất là T[0] -2
 Lần theo các chỉ số từ T[0] để in ra các phần tử thuộc dãy con đơn
điệu tăng dài nhất.

Page  30
Chương 7: QUI HOẠCH ĐỘNG

6. Dãy con chung dài nhất: Cho 2 dãy A, B.


A: a1, a2, .. , am
B: b1, b2, .. , bn
Hãy tìm dãy con chung dài nhất của A và B.
- Xâu con a của 1 xâu b là xâu có được sau khi xóa từ xâu b một số ký
tự.
B1: Dùng mảng 2 chiều để lưu trữ độ dài chung của 2 dãy L[0..m][0..n]
L[i][j]: là độ dài của dãy con chung dài nhất của 2 dãy:
a1, a2, .. , ai, b1, b2, .. , bj
B2: Cơ sở: L[0][j] = 0, j=1,n
L[i][0] = 0, i=1,m

Page  31
Chương 7: QUI HOẠCH ĐỘNG

k = L[n][m];
i=n; j=m;
while (i>0)
{ if (a[i]==b[j]) {printf (“%3d”, a[i]); i=i-1;j=j-1;} else
if (L[i-1][j] > L[i][j-1]) i=i-1; else j=j-1;
}
Page  32
Chương 7: QUI HOẠCH ĐỘNG

 Điền bảng L[i][j]


for(i = 0; i <= m; i++) L[i][0] = 0;
for(j = 0; j <= n; j++) L[0][j] = 0;
for(i = 1; i <= m; i++) {
for(j = 1; j <= n; j++) {
if(a[i] == b[j])
L[i][j] = L[i-1][j-1] + 1;
else
L[i][j] = max(L[i-1][j], L[i][j-1]);
}}
 In ra dãy con chung dài nhất
k = L[n][m];
i=n; j=m;
while (i>0)
{ if (a[i]==b[j]) {printf (“%3d”, a[i]); i=i-1;j=j-1;} else
if (L[i-1][j] > L[i][j-1]) i=i-1; else j=j-1; }
Page  33
Chương 7: QUI HOẠCH ĐỘNG

7. Tìm dãy con có tổng lớn nhất


Trung tâm tính toán hiệu năng cao nhận được đơn đặt hàng của n khách
hàng. Khách hàng i muốn sử dụng máy trong khoảng thời gian từ ai đến bi
và trả tiền thuê là ci. Hãy bố trí lịch thuê máy để tổng số tiền thu được là
lớn nhất mà thời gian sử dụng máy của 2 khách hàng bất kì được phục vụ
đều không giao nhau (cả trung tâm chỉ có một máy cho thuê)
Lời giải gợi ý: sắp xếp các đơn đặt hàng theo thời điểm kết thúc
Bài toán liên quan với 1 tham số: Số tiền lớn nhất  bảng phương án:
Mảng 1 chiều L[i] : Số tiền thu được lớn nhất khi xét đến công việc thứ i.
Cơ sở: L[i] = c[i], i=1,n
Truy hồi: L[i] = max(L[j] + c[i]), nếu (b[j] <=a[i]) && (j<i))

Page  34
Chương 7: QUI HOẠCH ĐỘNG

Cài đặt:
// Co so
L[0]=0;
for(i=1;i<=n;i++)
L[i]=v[i];
// Truy hoi
for(i=1;i<=n;i++)
for(j=i-1;j>0;j--)
if ((b[j]<=a[i])&&(L[j]+v[i]>L[i])) L[i]=L[j]+v[i];
Truy vết:
// So tien thu duoc cao nhat
int max=L[1];
int k;// Cong viec cuoi cung trong day cac cong viec cho thue
for(i=1;i<=n;i++)
if (L[i]>max) {max=L[i];k=i;}
printf("\n So tien cho thue duoc lon nhat: %d",max);
Page  35
Chương 7: QUI HOẠCH ĐỘNG

Truy vết:
while (k>0)
{ printf("\n cong viec thu %3d, bat dau: %3d, ket thuc: %3d",k,a[k],b[k]);
j=k-1;
while ((L[j]+v[k]!=L[k])||(b[j]!=a[k])) j=j-1;
k=j;
}

Page  36
Chương 7: QUI HOẠCH ĐỘNG

 Rèn luyện (tương tự)


Bố trí phòng họp (mất tính thứ tự so với dãy ban đầu)
Có n cuộc họp, cuộc họp thứ i bắt đầu vào thời điểm ai và kết thúc ở thời
điểm bi. Do chỉ có một phòng hội thảo nên 2 cuộc họp bất kì sẽ được cùng
bố trí phục vụ nếu khoảng thời gian làm việc của chúng chỉ giao nhau tại
đầu mút. Hãy bố trí phòng họp để phục vụ được nhiều cuộc họp nhất.

Lời giải gợi ý: sắp xếp các đơn đặt hàng theo thời điểm kết thúc
Bài toán liên quan với 1 tham số: Số cuộc họp nhiều nhất nhất khi xét đến
công việc thứ i.
Cơ sở: L[i] = 1, i=1,n
Truy hồi: L[i] = max(L[j] + 1), nếu (b[j] <=a[i]) && (j<i)

Page  37
Chương 7: QUI HOẠCH ĐỘNG

8. Bài toán xếp Balo: Một chiếc Balo có thể tích là Pmax.
Có n vật, vật thứ i có thể tích là: P[i] và giá trị w[i].
Hãy tìm cách xếp các vật vào Balo sao cho tổng giá trị là lớn nhất.

Giá trị của vali phụ thuộc vào 2 yếu tố:


- có bao nhiêu vật đang được xét
- Thể tích của các vật.
Do đó bảng phương án sẽ là bảng 2 chiều.

B1: Dùng mảng 2 chiều để lưu trữ phương án lấy vật L[0..n][0..Pmax]
L[i][j] : tổng giá trị lớn nhất của vali khi xét từ vật 1  vật i và thể tích
chưa vượt quá j.

B2: Cơ sở: L[0][j] = 0, j=1,Pmax


L[i][0] = 0, i=1,n

Page  38
Chương 7: QUI HOẠCH ĐỘNG

Page  39
Chương 7: QUI HOẠCH ĐỘNG

Bài toán xếp Balo:


- Điền bảng L[i][j]
// Cơ sở
for (j=0; i<=Pmax; j ++) L[0][j] =0;
for (i=0; i<=n i ++) L[i][0] =0;

// Truy hồi
for (i=1; i<=n; i ++)
for (j=1;j<=Pmax; j++)
{L[i][j] = L[i-1][j];
if ((j>=w[i]) && (L[i][j] < P[i]+ L[i-1][j-w[i]])
L[i][j]= P[i]+ L[i-1][j-w[i]];
}

Page  40
Chương 7: QUI HOẠCH ĐỘNG

Bài toán xếp Balo:


- In ra các phần tử được chọn

 Nếu L[n][Pmax] = L[n-1][Pmax]


 Vật thứ n không được chọn, xét L[n-1][Pmax]

 Nếu L[n][Pmax]  L[n-1][Pmax]


 Vật thứ n được chọn, in ra vật thứ n  xét L[n-1][Pmax-w[i]]

Quá trình in là dừng khi n=0

j= Pmax;
for (k=n; k>=0; k - -)
if (L[k][j] != L[k-1][j])
{ printf(“\n Vat thu: %3d, gia tri: %3d, the tich: %3d”,k,P[k],w[k]);
j=j-w[k];}
Page  41
Chương 7: QUI HOẠCH ĐỘNG

Page  42
Chương 7: QUI HOẠCH ĐỘNG

9. Tích n ma trận
Nhận xét: Số lượng phép toán nhân thực hiện phụ thuộc vào 2 tham số: số
hàng & số cột.  Bảng phương án: 2 chiều.
Tổ chức dữ liệu:
Kích thước của n ma trận được lưu thành 1 mảng n+1 phần tử.
Kích thước ma trận thứ i là: a[i]xa[i+1]

Gọi F[i][j] là số phép nhân cần thực hiện để nhân đoạn ma trận liên tiếp:
MiMi+1.….Mj (1  i  j  n).
Khi đó F[i][i] = 0 với mọi i.
Để tính Mi.Mi+1.….Mj ta có thể có nhiều cách kết hợp: Mi.Mi+1.….Mj =
(Mi.Mi+1.….Mk).(Mk+1.….Mj-1.Mj) với i  k <j. Với mỗi cách kết hợp (phụ
thuộc vào cách chọn vị trí k).

Page  43
Chương 7: QUI HOẠCH ĐỘNG

Page  44
Chương 7: QUI HOẠCH ĐỘNG

9. Tích n ma trận (tt)


A × B × C × D
[20×2] [2×30] [30×12] [12×8]
Điền bảng phương án:
F[i][i] = 0 j=1 2 3 4
i=1 0
for (i=1;i<=n;i++) F[i][i] =0; 2 0
3 0
4 0

Page  45
Chương 7: QUI HOẠCH ĐỘNG

9. Tích n ma trận
A × B × C × D
[20×2] [2×30] [30×12] [12×8]
Điền bảng phương án:
F[i][i+1] = aixai+1xai+2 j=1 2 3 4
Điền F[i][j]: Ví dụ i=1 0 1200 1200
F[1][3] = min { 2 0 720

F[1][1]+F[2][3] + a1xa2xa4, 3 0 2880


4 0
F[1][2] +F[3][3] + a1xa3xa4}

F[1][1] + F[2][3] + a1xa2xa4 = 0 + 720 + 20x2x12 = 720 + 480 =1200


F[1][2] + F[3][3] + a1xa3xa4 = 1200 + 0 + 20x30x12 = 1200 + 7200 = 8400
Page  46
Chương 7: QUI HOẠCH ĐỘNG

9. Tích n ma trận (tt)


Điền bảng F[i][j] llần lượt F[i][i+1], rồi F[i][i+2],.. Cho đến khi đặt được
F[1][n], i=n,..1
 Lưu lại cách gộp các ma trận để có được số lượng phép nhân nhỏ nhất:
 Sử dung bảng P[i][j]: P[i][j] = k (k là vị trí để (F[i][k] + F[k+1][j] + ai.ak+1.aj+1)
đạt min)
j=1 2 3 4
i=1 0 1 1 1
2 0 2 3 P[i][ j]
3 0 3
4 0

Page  47
Chương 7: QUI HOẠCH ĐỘNG

9. Tích n ma trận (tt)


MATRIX-CHAIN-ORDER(int a[], int n)
for (i=1;i<=n; i++)
F[i][i]=0;
for (l=2;l<=n;l++)
for (i=1;i<= n-l+1;i++)
{ j←i+l-1;
F[i][j]← ∞;
for (k=i ; k<= j-1;k++)
{ q= min(F[i][k] + F[k+1][j] + ai.ak+1.aj+1);
if (q < F[i][j] )
F[i][j] =q ;
P[i][j] =k; }
// return F[1][n]

Page  48
Chương 7: QUI HOẠCH ĐỘNG

 Bài tập làm thêm


 Bài tập trong tài liệu Giải thuật và lập trình Mục 3.6, trang 172, Lê Minh
Hoàng)
 Bài tập: Slide Cấu trúc & thuật giải (ĐH Lạc Hồng, Tạ Thúc Nhu)
 https://www.geeksforgeeks.org/dynamic-programming/

Page  49
Cám ơn đã theo dõi

Page  50

You might also like