Escolar Documentos
Profissional Documentos
Cultura Documentos
Tại sao không viết hẳn chương trình ra để đánh giá hiệu quả
thuật toán:
Việc cài đặt chương trình rất tốn thời gian.
Tốc độ chạy chương trình trên các máy khác nhau là khác
nhau
Máy của thí sinh vs. Máy của giám khảo
Không chương trình nào chạy hai lần trên cùng một máy.
Độ phức tạp tính toán là một cách biểu diễn số phép tính
thuật toán cần thực hiện so với kích thước đầu vào.
Tính số phép tính của thuật toán sau theo n: Một đáp án có thể:
f (n) = n3 + 12 n(n + 1)
Gọi f (n) là số phép tính thuật toán cần thực hiện nếu độ lớn của
dữ liệu vào là n (n có thể là độ dài mảng, độ lớn của số nguyên
được cho, ...)
(Để đơn giản, từ giờ cho đến hết bài trình bày này, chúng ta sẽ
quy ước hàm f có tập xác định là tập số nguyên dương và tập giá
trị là tập số thực dương)
Một số tập O hay gặp: O(1), O(log n), O(n2 ), O(n3 ), O(2n ), O(n!)
Tính chất 1
f (n) ∈ O(f (n))
Tính chất 2
Cho hàm f (n) ∈ O(g (n)) và c > 0. Khi đó cf (n) ∈ O(g (n))
Lấy hàm f (n), g (n) và số c bất kì sao cho f (n) ∈ O(g (n)) và
c>0
Do f (n) ∈ O(g (n)) nên ∃n0 , c > 0 : ∀n ≥ n0 : f (n) ≤ c · g (n)
và vì thế ta có thể chọn số n1 , c1 > 0 sao cho
∀n ≥ n1 : f (n) ≤ c1 · g (n)
Để chứng minh cf (n) ∈ O(g (n)), ta cần chứng minh
∃n2 , c2 > 0 : ∀n ≥ n2 : cf (n) ≤ c2 · g (n)
Chọn n2 = ... > 0, c2 = ... > 0
Chọn số n ≥ n2 bất kì
Do ∀n ≥ n1 : f (n) ≤ c1 · g (n) và n ≥ n2 ≥ n1 , f (n) ≤ c1 · g (n)
⇒ cf (n) ≤ cc1 · g (n) ⇒ cf (n) ≤ c2 · g (n)
Lấy hàm f (n), g (n) và số c bất kì sao cho f (n) ∈ O(g (n)) và
c>0
Do f (n) ∈ O(g (n)) nên ∃n0 , c > 0 : ∀n ≥ n0 : f (n) ≤ c · g (n)
và vì thế ta có thể chọn số n1 , c1 > 0 sao cho
∀n ≥ n1 : f (n) ≤ c1 · g (n)
Để chứng minh cf (n) ∈ O(g (n)), ta cần chứng minh
∃n2 , c2 > 0 : ∀n ≥ n2 : cf (n) ≤ c2 · g (n)
Chọn n2 = n1 > 0, c2 = cc1 > 0
Chọn số n ≥ n2 bất kì
Do ∀n ≥ n1 : f (n) ≤ c1 · g (n) và n ≥ n2 = n1 , f (n) ≤ c1 · g (n)
⇒ cf (n) ≤ cc1 · g (n)
⇒ cf (n) ≤ c2 · g (n)
Do cách ta chọn n2 , c2 , n, ta có thể kết luận:
∃n2 , c2 > 0 : ∀n ≥ n2 : cf (n) ≤ c2 · g (n)
Bùi Việt Dũng Đánh giá hiệu quả thuật toán
Ứng dụng tính chất 2
Tính chất 2
Cho hàm f (n) ∈ O(g (n)) và c > 0. Khi đó cf (n) ∈ O(g (n))
Xét thuật
P toán
Psau:
f (n) = ni=1 nj=1 8 = 8n2 ∈ O(n2 )
g (n) = ni=1 nj=1 1 = n2 ∈ O(n2 )
P P
Tính chất 3
Nếu f (n) ≤ g (n) thì O(f (n)) ⊂ O(g (n))
Giả sử ta có hai hàm f (n), g (n) sao cho f (n) < g (n)
Để chứng minh O(f (n)) ⊂ O(g (n)), ta cần chứng minh:
∀h(n) ∈ O(f (n)) : h(n) ∈ O(g (n))
Chọn hàm h(n) ∈ O(f (n)) bất kì
Khi đó ∃n0 , c > 0 : ∀n ≥ n0 : h(n) ≤ cf (n)
Do f (n) ≤ g (n) nên điều này nghĩa là
∃n0 , c > 0 : ∀n ≥ n0 : h(n) ≤ cg (n)
⇒ h(n) ∈ O(g (n))
Do ta chọn h(n) ∈ O(f (n)) bất kì, ta có thể kết luận
O(f (n)) ⊂ O(g (n)) và đây là điều phải chứng minh.
Tính chất 4
Nếu f1 (n) ∈ O(g1 (n)) và f2 (n) ∈ O(g2 (n)) thì
f1 (n)f2 (n) ∈ O(g1 (n)g2 (n))
Tính chất 5
Nếu f1 (n) ∈ O(g1 (n)) và f2 (n) ∈ O(g2 (n)) thì
f1 (n) + f2 (n) ∈ O(max{g1 (n), g2 (n)})
Tính chất 6
Nếu f (n) ∈ O(g (n)) và g (n) ∈ O(h(n)) thì f (n) ∈ O(h(n))
Ứng dụng
Chứng minh rằng O(8n2 ) = O(n2 )
Chọn f (n) ∈ O(8n2 ) bất kì. Ta có 8n2 ∈ O(n2 ) (dùng tính chất 2,
chọn c = 8 > 0) nên theo tính chất 6,
f (n) ∈ O(n2 ) ⇒ O(8n2 ) ⊂ O(n2 )
Chọn f (n) ∈ O(n2 ) bất kì. Ta có n2 ∈ O(8n2 ) (dùng tính chất 2,
chọn c = 18 > 0) nên theo tính chất 6,
f((n) ∈ O(8n2 ) ⇒ O(n2 ) ⊂ O(8n2 )
O(8n2 ) ⊂ O(n2 )
⇒ O(n2 ) = O(8n2 )
O(n2 ) ⊂ O(8n2 )
Tính chất 7
Nếu lim gf (n)
(n) = c với c là một số thực không âm thì
f (n) ∈ O(g (n))
Tính chất 8
Nếu f (n) = a1 nb1 + a2 nb2 + ... + ad nbd với
a1 , a2 , ..., ad , b1 , b2 , ..., bd > 0, b1 > b2 > ... > bd thì
f (n) ∈ O(nb1 )
Ta có
b1 b2 bd b1 b2
lim a1 n +a2 nnb1+...+ad n = lim an1 nb1 + lim an2 nb1 + ... =
a1 + 0 + 0 + ... = a1
nên theo tính chất 7, f (n) ∈ O(nb1 )
Thuật toán có độ phức tạp O(nd ) với một số thực d > 0 được gọi
là thuật toán có độ phức tạp đa thức.
O(log n)
Độ phức tạp của thuật toán tìm kiếm nhị phân
√
O( n)
Độ phức tạp của thuật toán kiểm tra số nguyên tố.
O(n)
Độ phức tạp của thuật toán tìm kiếm tuần tự.
O(n log n)
Độ phức tạp của hàm sort trong C++
Bùi Việt Dũng Đánh giá hiệu quả thuật toán
Một số độ phức tạp tính toán thường gặp
O(n2 )
Độ phức tạp của thuật toán Quicksort và hàm sort trong Java
O(2n )
Duyệt hết các tập con của một tập có n phần tử.
O(n!)
Duyệt hết các hoán vị của một tập có n phần tử.
Giả sử ta nhìn được độ phức tạp của chương trình là O(f (n)), ta
có thể ước lượng độ phức tạp của thuật toán như sau:
Lấy n lớn nhất có thể có trong dữ liệu vào (được cho trong đề
bài), tính f (n)
Tính f10
(n) 8
8 = t (do máy tính thông thường tính được 10 phép
tính một giây)
Chương trình sẽ chạy trong thời gian ct với c là một hằng số
nào đó.
Nếu t ≤ 0.1 thì thường chương trình sẽ chạy dưới 1 giây. Nếu
t > 0.1 thì ta cố gắng tính tiếp hằng số c. Nếu ct ≤ 1 thì chương
trình nhiều khả năng sẽ chạy dưới 1 giây.
Đối với các kì thi dành cho học sinh cấp 3 thì việc thừa log n trong
độ phức tạp sẽ không gây hậu quả gì lớn.
Nếu có hai cách cài đặt, một cách O(n log n) nhưng dài và
cách còn lại có độ phức tạp O(n log2 n) nhưng ngắn hơn thì
ta chọn cách thứ hai.
Nếu chỉ nghĩ ra cách O(n log2 n) mà không ra cách tối ưu
xuống còn O(n log n) thì không nên bỏ tiếp thời gian để nghĩ
mà cài thuật O(n log n)
Phản ví dụ: Con đường Tùng Trúc (VOI 2014), Street Lamps
(APIO 2019)
Nhận thấy:
Pn
i=1 1 = n
Pn Pi Pn 1
i=1 j=1 1 = i=1 i = 2 n(n + 1)
Pn Pi Pj Pn 1 1
i=1 j=1 z=1 1 = i=1 2 i(i + 1) = 6 n(n + 1)(n + 2)
Pn Pi Pj Pz Pn 1
i=1 j=1 z=1 k=1 1 = i=1 6 n(n + 1)(n + 2) =
1
24 n(n + 1)(n + 2)(n + 3)
Nếu ta có k vòng lặp lồng nhau, biến lặp sau chỉ chạy đến biến lặp
trước thì tổng số phép tính cần thực hiện là
1
k! n(n + 1)(n + 2)...(n + k)
(Chứng minh bằng quy nạp hoặc sử dụng kiến thức tổ hợp)
Ứng dụng: Bài VTRI - VNOI Marathon 2008
Cho n (n ≤ 105 ) bóng đèn được đánh số từ 1 đến n. Ban đầu, các
bóng đèn đều tắt. Thực hiện q truy vấn (q ≤ 105 ) sau:
1 Cho hai số nguyên l, r (1 ≤ l ≤ r ≤ n). Bật các bóng đèn
l, l + 1, l + 2, ..., r
2 Cho hai số nguyên l, r (1 ≤ l ≤ r ≤ n). Tắt các bóng đèn
l, l + 1, l + 2, ..., r
3 Tìm bóng đèn được bật có chỉ số nhỏ nhất.
n
Do b> 0 và 2b > 0, theo bất đẳng thức AM - GM, ta có
n
pn √ √
+ 2b ≥ 2 · 2b = 2 2 n
b b √ √
⇒ q( bn + 2b) ≥ 2 2q n
(Khi n = 105 , ta p
chọn b = 224) √ √ √
Khi ta chọn b = n2 thì ta sẽ cần 2 2q n ∈ O(q n) phép tính.
√
Như vậy là ta đã giảm được độ phức tạp từ O(qn) xuống O(q n)
Bài toán
Cho một mảng a gồm n số nguyên dương và một số nguyên dương
S. Tìm một dãy con liên tiếp của mảng a sao cho tổng của dãy
con bằng S
Thuật O(n3 )?
Thuật O(n2 )?
Thuật O(n)?
Nhận xét
Nếu ri=l ai < S thì ∀l + 1 ≤ j ≤ r : ji=l+1 ai ̸= S
P P
P −1
Giả sử ri=l ai < S. Ta cần chứng minh
∀l + 1 ≤ j ≤ r : ji=l+1 ai < S
P
Chọn jP P1 ≤ j ≤ r
bất kì sao cho l +
Ta có ji=l+1 ai < al + ri=l+1 ai (do al > 0)
⇒ ji=l+1 ai < ri=l ai < S ⇒ ji=l+1 ̸= S
P P P