## 1025. Divisor game
**Game theory cơ bản**:
- Trạng thái tầm thường: không thể đi thêm một nước nào nữa -> chắc chắn thua.
- Nếu một trạng thái nào đó đẩy được đối thủ về trạng thái tầm thường -> chắc chắn thắng.
- Nếu một trạng thái nào đó chỉ có thể đẩy đối phương vào trạng thái chắc chắn thắng -> chắc chắn thua.
- Nếu một trạng thái nào đó đẩy được đối thủ vào một trạng thái thua -> chắc chắn thắng.
Từ trạng thái phức tạp hơn -> trạng thái đơn giản. -> DP.
## 72. Edit distance
-> đọc lại LCS (Longest common subsequence).
## 494. Target Sum
Có 2 cách giải:
1. Backtrack $O(2 ^ n)$ (do $n \le 20$)
-> Lưu ý: để backtrack khéo, ta nên lưu thêm 1 params vào hàm backtrack:
`backtrack(int x, int sum)` -> khi đó, ta không cần phải duyệt +- lại từ đầu sau khi sinh được xong một config nữa, mà tính luôn.
3. DP
$f(i, j)$ = có bao nhiêu cách để tạo ra các biểu thức sử dụng $A[1..i]$, sao cho tổng bằng đúng $j$.
$0 \le i \le 20$
$-20000 \le j \le 20000$
-> để lưu kết quả DP, các bạn sẽ phải sử dụng 1 trong 2 kỹ thuật:
- Dùng map, hoặc unordered_map để lưu trữ các phần tử index âm.
- Transpose $j' = j + 20001$ để sử dụng các index dương trong array.
Sau đó, viết công thức DP như bình thường.
## 741. Cherry Pickup
Code mẫu (low_): https://leetcode.com/problems/cherry-pickup/submissions/1281386537
Đầu tiên, các bạn hãy thử giải với trường hợp đi 1 chiều?
$dp(i, j) = -inf$ (nếu $a[i][j] == -1$, hoặc $i < 0, j < 0$)
$dp(i, j) = max(dp(i - 1, j), dp(i, j - 1)) + a[i][j]$
Để chọn ra cùng lúc 2 đường, mà tổng hai đường có số cherry nhặt được tối ưu nhất, ta cần lưu cả 2 tọa độ hiện thời: $(i, j)$ và $(u, v)$:
$dp(i, j, u, v)$ = max(dp(i - 1, j, u - 1, v), dp(i - 1, j, u, v - 1), ...) + ...$
$1 \le i, j, u, v \le n \le 50$
-> hoàn toàn $O(n ^4)$ có thể chạy được.
$i + j == u + v$
-> Có thể cải tiến rằng chỉ lưu $dp(i, j, u)$, khi đó, có thể tính $v = i + j - u$ và tiếp tục chuyển trạng thái.
-> cải tiến được bộ nhớ xuống $O(n^3)$.
## 32. Longest Valid Parentheses
https://leetcode.com/problems/longest-valid-parentheses/submissions/1284748445/
Luồng suy nghĩ WA và cải tiến bằng DP được comment ở trong đoạn code trên.
Lưu ý: kỹ thuật tìm vị trí ngoặc mở tương ứng với từng ngoặc đóng sử dụng stack.
## 174. Dungeon Game
Quan sát: nếu một ngưỡng máu $x$ nào đó mà có thể thỏa mãn nhân vật có thể đi đến cuối mà vẫn sống, thì với mọi ngưỡng máu $y >= x$ -> nhân vật cũng sẽ sống.
-> Binary search để tính ra ngưỡng máu.
Câu hỏi: với một ngưỡng máu $x$ nhất định nào đó, thì ta tính ra xem nhân vật có thể đi đến cuối ngục được không?
$dp(i, j)$ ngưỡng máu tối đa mà nhân vật có thể dư lại khi đi đến ô $(i, j)$. -> Nếu ngưỡng máu tối đa mà = 0 hoặc âm, thì $dp(i, j) = -inf$
## 42. Trapping Rain Water
https://leetcode.com/problems/trapping-rain-water/submissions/1283621119/?envType=problem-list-v2&envId=mlayhpdh