.c
om
an
co
ng
THUẬT TỐN ỨNG DỤNG
cu
u
du
o
ng
th
CHIA ĐỂ TRỊ
Phạm Quang Dũng
Bộ mơn KHMT
1
CuuDuongThanCong.com
/>
.c
om
NộI dung
Tổng quan chia để trị
ng
Ví dụ minh họa
cu
u
du
o
ng
th
an
Giảm để trị
co
Độ phức tạp chia để trị
2
CuuDuongThanCong.com
/>
.c
om
Tổng quan chia để trị
Chia bài toán cần giải ban đầu thành các bài toán con
cu
u
du
o
ng
th
an
co
ng
độc lập nhau
Giải (trị) các bài toán con
Tổng hợp lời giải của các bài toán con để dẫn ra lời
giải của bài toán xuất phát
3
CuuDuongThanCong.com
/>
.c
om
Ví dụ minh họa
Bài tốn dãy con dài nhất: cho dãy số nguyên a = a1,
ng
th
an
co
ng
a2, …, an. Tìm dãy con gồm một số liên tiếp các phần
tử có tổng lớn nhất
Phân chia: ký hiệu P(i, j) là lời giải của bài tốn tìm dãy
con liên tiếp của dãy ai, ai+1,…, aj có tổng cực đại
Tổng hợp lời giải
du
o
Ký hiệu PL(i, j) là lời giải của bài tốn tìm dãy con liên tiếp
cu
u
của dãy ai, ai+1,…, aj sao cho phần tử cuối cùng là aj có
tổng cực đại
Ký hiệu PR(i, j) là lời giải của bài tốn tìm dãy con liên
tiếp của dãy ai, ai+1,…, aj sao cho phần tử đầu tiên là ai
có tổng cực đại
4
CuuDuongThanCong.com
/>
.c
om
Ví dụ minh họa
Xét đoạn [l,l+1,...,r]. Ký hiệu m = (l+r)/2
P(l,m)
th
m m+1
P(m+1,r)
cu
u
du
o
ng
l
an
co
ng
P(l,r) = MAX{P(l, m), P(m+1,r), PL(l,m) + PR(m+1,r)}
PL(l,m)
PR(m+1,r)
5
CuuDuongThanCong.com
/>
r
.c
om
Ví dụ minh họa
#include <bits/stdc++.h>
using namespace std;
ng
#define INF 1e9
co
#define MAX 1000000
an
int a[MAX];
th
int n;
ng
void input(){
cin >> n;
cu
u
}
du
o
for(int i = 0; i < n; i++) cin >> a[i];
6
CuuDuongThanCong.com
/>
ng
co
an
th
ng
int PL(int l, int r){
int rs = -INF;
int s = 0;
for(int i = r; i >= l; i--){
s += a[i];
rs = max(rs,s);
}
return rs;
}
.c
om
Ví dụ minh họa
cu
u
du
o
int PR(int l, int r){
int rs = -INF;
int s = 0;
for(int i = l; i <= r; i++){
s += a[i];
rs = max(rs,s);
}
return rs;
}
7
CuuDuongThanCong.com
/>
.c
om
Ví dụ minh họa
int P(int l, int r){
if(l == r) return a[r];
ng
int m = (l+r)/2;
co
return max(max(P(l,m),P(m+1,r)), PL(l,m)+PR(m+1,r));
}
an
void solve(){
th
cout << P(0,n-1);
ng
}
solve();
cu
}
u
input();
du
o
int main(){
8
CuuDuongThanCong.com
/>
Chia bài toán xuất phát thành a bài
1.
𝑏
cu
u
1 ,
𝑛 ≤ 𝑛0
T 𝑛 =ቐ
𝑛
𝑎𝑇
+ 𝐶 𝑛 + 𝐷 𝑛 , 𝑛 > 𝑛0
if(n n0)
ng
2.
3.
co
du
o
ng
toán con, mỗi bài toán con kích
thước n/b
T(n): thời gian của bài tốn kích
thước n
Thời gian phân chia (dòng 4): D(n)
Thời gian tổng hợp lời giải (dịng 6):
C(n)
Cơng thức truy hồi:
an
procedure D-and-C(n) {
th
.c
om
Độ phức tạp tính tốn
xử lý trực tiếp
else{
4.
chia bài tốn xuất phát
thành a bài tốn con kích thước
n/b
5.
gọi đệ quy a bài tốn con
6.
tổng hợp lời giải
7.
}
}
9
CuuDuongThanCong.com
/>
.c
om
Độ phức tạp tính tốn
Độ phức tạp của thuật tốn chia để trị (định lí thợ)
ng
Cơng thức truy hồi:
cu
u
du
o
ng
th
an
co
T(n) = aT(n/b) + cnk, với các hằng số a 1, b > 1, c > 0
Nếu a > bk thì T(n) = (𝑛𝑙𝑜𝑔𝑏 𝑎 )
Nếu a = bk thì T(n) = (𝑛𝑘 𝑙𝑜𝑔𝑛) với logn = 𝑙𝑜𝑔2 𝑛
Nếu a < bk thì T(n) = (𝑛𝑘 )
10
CuuDuongThanCong.com
/>
.c
om
Độ phức tạp tính tốn
Độ phức tạp của thuật tốn chia để trị (định lí thợ)
ng
Cơng thức truy hồi:
du
o
ng
th
an
co
T(n) = aT(n/b) + cnk, với các hằng số a 1, b > 1, c > 0
Nếu a > bk thì T(n) = (𝑛𝑙𝑜𝑔𝑏 𝑎 )
Nếu a = bk thì T(n) = (𝑛𝑘 𝑙𝑜𝑔𝑛) với logn = 𝑙𝑜𝑔2 𝑛
Nếu a < bk thì T(n) = (𝑛𝑘 )
cu
u
→ Thuật toán chia để trị giải bài toán tổng con cực đại có
độ phức tạp là O(nlogn)
11
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Phân chia: Chia dãy a1, …, an thành 2 dãy con có độ dài bằng
cu
u
du
o
ng
th
an
co
ng
nhau
Trị đệ quy: Sắp xếp 2 dãy con bằng thuật toán sắp xếp trộn
Tổng hợp: Trộn 2 dãy con đã được sắp với nhau để thu được
dãy ban đầu được sắp thứ tự
12
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
i
co
j
ng
xếp
3
8
9
20
4
an
1
5
10
11
23
u
ta
cu
k
du
o
ng
th
a
13
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
i
co
j
ng
xếp
3
8
9
20
4
an
1
5
10
11
23
1
cu
ta
u
k
du
o
ng
th
a
14
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
i
co
j
ng
xếp
3
8
9
20
4
an
1
5
10
11
23
du
o
ng
th
a
1
cu
ta
u
k
3
15
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
xếp
i
co
ng
j
3
8
9
20
4
an
1
5
10
11
23
du
o
ng
th
a
1
cu
ta
u
k
3
4
16
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
j
5
10
co
i
ng
xếp
3
8
9
20
4
an
1
11
23
1
cu
ta
k
u
du
o
ng
th
a
3
4
5
17
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
j
5
10
co
i
ng
xếp
3
8
9
20
4
an
1
11
23
du
o
ng
th
a
u
1
cu
ta
k
3
4
5
8
18
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
j
5
10
co
i
ng
xếp
3
8
9
20
4
an
1
11
23
du
o
ng
th
a
u
1
cu
ta
k
3
4
5
8
9
19
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
xếp
j
co
ng
i
3
8
9
20
4
an
1
5
10
11
23
du
o
ng
th
a
u
1
cu
ta
k
3
4
5
8
9
10
20
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
xếp
j
co
ng
i
3
8
9
20
4
an
1
5
10
11
23
du
o
ng
th
a
u
1
cu
ta
k
3
4
5
8
9
10
11
21
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
j
co
ng
xếp
3
8
9
20
4
an
1
5
10
11
23
du
o
ng
th
a
u
1
cu
ta
k
3
4
5
8
9
10
11
20
23
22
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
co
ng
xếp
3
8
9
20
4
an
1
5
10
11
23
ng
th
a
1
cu
ta
u
du
o
copy
3
4
5
8
9
10
11
20
23
23
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
Trộn hai dãy đã được sắp xếp thành dãy mới được sắp
co
ng
xếp
ta
1
3
4
5
8
9
10
11
20
23
9
10
11
20
23
an
1
cu
u
du
o
ng
th
a
3
4
5
8
24
CuuDuongThanCong.com
/>
.c
om
Sắp xếp trộn
#include <bits/stdc++.h>
using namespace std;
ng
#define MAX 1000000
co
int a[MAX];
int n;
th
an
int ta[MAX];
ng
void input(){
cin >> n;
}
cu
void print(){
u
du
o
for(int i = 0; i < n; i++) cin>> a[i];
for(int i = 0; i < n; i++) cout << a[i] << " ";
}
25
CuuDuongThanCong.com
/>