---
# System prepended metadata

title: '[Ams 2024] Chữa bài 11/06/2024'

---

## 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

