Professional Documents
Culture Documents
1 năm - 12 tháng
Mỗi tháng có 8 buổi
7 buổi học về lý thuyết + bài tập
buổi số 8 là buổi làm một bài test để review kiến thức đã học trong tháng đó
Mỗi buổi học từ 19h30 -> 22h00, tối thứ 2 và thứ 6 hàng tuần.
Mỗi buổi học luôn có video quay lại.
Giai đoạn 1: (6 tháng đầu tiên - những kiến thức căn bản trong sách giáo khoa
chuyên tin mà một bạn học chương trình thuật toán phải biết)
- Tháng 5: Toán
+ Combinatorics
+ Dynamic Programming + Combinatorics
+ Xác suất
+ Kỳ vọng
+ Lý thuyết trò chơi
+ Phi hàm Euler
+ Một số phương pháp chứng minh trong toán học
+ Kỳ thi cuối tháng
Giai đoạn 2 (6 tháng sau - Dành cho những bạn muốn thi bảng siêu cúp, hoặc muốn có
giải 3 đổ lên của kỳ thi acm icpc, hoặc giải 3 học sinh giỏi quốc gia đổ lên)
-----------------------------------------------------------------------------------
-------------------------------------------------
Khi ta thiết kế thuật toán. Để giải quyết cùng một vấn đề P, làm sao để có thể đo
lường được thuật toán nào tốt, thuật toán nào chưa tốt
Một chiếc máy tính bình thường, có thể xử lý tối đa 10 triệu phép tính / giây
Trong lập trình thi đấu, với những đề bài thuật toán, người ta thường giới hạn thời
gian để đưa ra được kết quả. Việc tối ưu về mặt độ phức tạp thuật toán là
ta phải thực hiện một thuật toán sao cho số lượng bước thực thi không vượt quá số
lượng bước có thể cho phép.
Khi đánh giá độ phức tạp thuật toán, ta phải xét thời gian mà thuật toán thực thi
trong trường hợp chậm nhất
O(1): Khi ta thiết kế những thuật toán chỉ chạy trong một vài bước (với số lượng
bước là số nhỏ)
Ví dụ: Kiểm tra N có phải là số chẵn / lẻ, Kiểm tra 3 số a, b, c có phải là độ dài
3 cạnh tam giác hay không ?
O(logN):
for i: 1 -> N, i = i * 2
Nếu N = 5000
i = 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 (dừng)
O(căn(N)): Khi ta thiết kế thuật toán với số bước thực hiện trong căn(N)
for i: 1 -> N
res = res + a[i]
O(N^c): Khi ta thiết kế thuật toán chạy với nhiều vòng lặp tuyến tính LỒNG NHAU:
for i: 1 -> N
for j: N -> 1
for k: 1 -> N
O(N^3)
O(2^n): Đây là độ phức tạp thuật toán xuất hiện khi ta liệt kê tất cả các tập hợp
của một dãy số.
O(n!): Đây là độ phức tạp thuật toán khi ta liệt kê toàn bộ trường hợp có thể xảy
ra.
Nếu thuật toán được hợp bởi nhiều thuật toán nhỏ có độ phức tạp giống nhau thì độ
phức tạp tổng quát sẽ là độ phức tạp của thuật toán nhỏ đó.
for i: 1 -> N
cout << a[i] << ' ';
for i: 1 -> N
cout << b[i] << ' ';
Nếu thuật toán được hợp bởi nhiều thuật toán có độ phức tạp khác nhau, thì độ phức
tạp thuật toán tổng uqát sẽ được lấy bởi độ phức tạp của thuật toán chạy chậm nhất
trong những thuật toán đã cho
for i: 1 -> N:
cout << a[i] << ' ';
for i: 1 -> N, i = i + 2
for j: N -> 1, j = j - 1
sum = sum + a[i] + a[j]
Nếu ta có thuật toán được lồng nhau bởi 2 hoặc nhiều thuật toán thì độ phức tạp
thuật toán tổng quát sẽ bằng tích các độ phức tạp thuật toán thành phần
for i: 1 -> N, i = i * 2
for j: 1 -> N, j = j + 1
O(log(N) * N)
Trong Competitive Programming, ta hãy đánh giá độ phức tạp thuật toán làm sao để số
bước thực thi không vượt quá số bước mà đề cho phép.
Hàm sort: Đây là hàm sắp xếp các giá trị trong một dãy số theo thứ tự tăng dần
(hoặc theo thứ tự mà người ta mong muốn)
#include <algorithm>
Nếu ta muốn sắp xếp tăng dần các phần tử từ vị trí [l .. r]:
sort(a + l, a + r + 1);
Ví dụ:
a = [5, 1, 2, 9, 4, 6, 7, 3, 3, 5, 2, 4, 1]
sort(a + 2, a + 8);
a = [5, 1, 2, 4, 6, 7, 9, 3, 3, 5, 2, 4, 1]