Vì vậy ta cần cải tiến lên Onlogn cụ thể là sử dụng cấu trúc dữ liệu SegmentTree để thực hiện trạng thái quy hoạch động.. => Ta sử dụng một cây SegmentTree để lưu lại giá trị mảng dp của
Trang 1S GD&ĐT TP ĐÀ N NG Ở Ẵ
TR ƯỜ NG THPT CHUYÊN
LÊ QUÝ ĐÔN
KỲ THI CH N H C SINH GI I Ọ Ọ Ỏ KHU V C DUYÊN H I VÀ Đ NG B NG B C B Ự Ả Ồ Ằ Ắ Ộ
NĂM H C 2021 – 2022 Ọ
Thời gian 180 phút (không kể thời gian giao đề)
H ƯỚ NG D N CH M Ẫ Ấ
BÀI 1: Có 50 test, m i test 0.12 đi m ỗ ể
Subtask 1: G i dp[i] là t ng s c kho l n nh t c a các b n h c sinh khi th y Baọ ổ ứ ẻ ớ ấ ủ ạ ọ ầ
ch n ngọ ườ ầi đ u tiên là b n th i T đó ta có công th c quy ho ch đ ng nh sau:ạ ứ ừ ứ ạ ộ ư
dp[i] = ai; dp[i] = max(dp[i], dp[j] + a[i]) (Li <= j <= Ri) Dùng for duy t i t n v 1, dùng thêm 1 for đ duy t j t Li đ n Ri.ệ ừ ề ể ệ ừ ế
=> Đpt: O(n2)
Subtask 2: C i ti n t subtask 1 Thay vì dùng for th 2 đ duy t j t Li đ n Ri taả ế ừ ứ ể ệ ừ ế
s d ng c u trúc d li u segment tree v i 2 thao tác l y max 1 đo n [Li, Ri] vàử ụ ấ ữ ệ ớ ấ ạ
c p nh t giá tr dp[i] lên cây.ậ ậ ị
=> Đpt: O(n*logn)
BÀI 2: Có 20 test, m i test 0.35 đi m ỗ ể
Subtask 1: V i subtask này ta sẽ duy t h t t t c n * m ô và dùng thu t toán DFSớ ệ ế ấ ả ậ
ho c BFS m i ô đ tính giá tr đặ ở ỗ ể ị ường đi xu t phát t ô đó (đấ ừ ường đi không quá
n * m ô) v y đ ph c t p là n ^ 2 * m ^ 2 = n ^ 4 = 50 ^ 4 = 6250000 có th ch yậ ộ ứ ạ ể ạ
dưới 1 giây
=> Đpt: O(n4)
Subtask 2: Ta xem m i ô trên b ng hình ch nh t là m i đ nh thu c đ th Taỗ ả ữ ậ ỗ ỉ ộ ồ ị
đ a bài toán v DAG (đ th có hư ề ồ ị ướng, không có chu trình) b ng cách nén các chuằ trình l i thành m t đ nh l n, v i m i đ nh l n sẽ mang giá tr là t ng giá tr cácạ ộ ỉ ớ ớ ỗ ỉ ớ ị ổ ị
đ nh nh bên trong Ta s p x p topo trên đ th đ có đỉ ỏ ắ ế ồ ị ể ược tr t t topo, v y v iậ ự ậ ớ
m i đ nh thì đ nh mà nó n i đ n sẽ n m phía sau nó sau khi s p x p topo Taỗ ỉ ỉ ố ế ằ ở ắ ế
s d ng quy ho ch đ ng c b n b ng cách g i f[u] là giá tr l n nh t c a cácử ụ ạ ộ ơ ả ằ ọ ị ớ ấ ủ
Trang 2đường đi xu t phát trấ ước đó đ n đ nh u và c t nh p cho các đ nh phía sau d aế ỉ ậ ậ ỉ ự vào danh sách k ề
L u ý: ư Vì robot sẽ d ng l i khi đi h t chu trình vì v y lúc dp c n ki m tra xemừ ạ ế ậ ầ ể
đ nh hi n t i có ph i là đ nh l n không ỉ ệ ạ ả ỉ ớ
=> Đpt: O(n2)
BÀI 3: Có 100 test, m i test 0.07đi m ỗ ể
Sub 1: Cày trâu với DP O(n2)
Sub 2: Ta có thể thấy n2 quá lớn để làm được sub này Vì vậy ta cần cải tiến lên O(nlog(n)) cụ thể là sử dụng cấu trúc dữ liệu SegmentTree để thực hiện trạng thái quy hoạch động
Đặt dp[i] : Số điểm cao nhất có thể đạt được khi chia i phần tử đầu tiên theo yêu cầu của đề => Đáp án của bài toán là dp[n]
Gọi f(L, R) là số điểm đạt được khi chia từ L đến R vào 1 nhóm
Để tính dp[i], ở sub 1 ta cần chạy biến j từ i - 1 về 1 để thực hiện dp[i] = max(dp[i], dp[j] + f(j + 1, i))
Thao tác này mất O(n) ở mỗi i và cho ra thuật toán mất O(n2), tuy nhiên ta có thể giảm
độ phức tạp ở bước này xuống O(logn) bằng cách sử dụng cấu trúc SegmentTree, đủ tốt để vượt qua bài toán này
=> Ta sử dụng một cây SegmentTree để lưu lại giá trị mảng dp của dãy
Khi ta đang đứng ở vị trí i, giả sử i sẽ là phần tử có giá trị b cao thứ hai của nhóm hiện tại Vì là phần tử có giá trị b cao thứ 2 nên tồn tại một vị trí j có b[j] > b[i] Ta xét 2 trường hợp j < i và j > i
=> Thực hiện các thao tác Update giá trị của một đoạn và Query Get Max của một đoạn để giải quyết bài toán này
Giáo viên
Nguy n H u Siêuễ ữ