---
# System prepended metadata

title: 518. Coin Change II (Lowie)

---

# 1. Tóm tắt đề bài

Cho một dãy $coins$ gồm toàn các số nguyên, thể hiện các mệnh giá của các đồng tiền có ở nước bạn.

Có bao nhiêu cách để quy đổi giá trị $amount$ thành tổng các đồng tiền khác nhau?

2 cách đồi tiền khác nhau khi tồn tại một mệnh giá $x$ nào đó, mà số lần sử dụng đồng tiền mệnh giá $x$ ở cả hai cách là khác nhau.

##### Giới hạn

$1 \le coins.length \le 300$

$1 \le coins[i] \le 5000$

$0 \le amount \le 5000$

Tất cả các giá trị trong $coins$ đều phân biệt.

# 2. Tóm tắt lời giải

**Độ phức tạp dự tính: $O(n * amount)$**

Ta có thể nghĩ đơn giản đến một mảng $dp(i)$ để tính số cách tạo ra $i$ đồng từ các đồng tiền mệnh giá đã cho:

$dp(i) = \sum_{j = 0}^{n - 1} dp(i - coins[j])$

Tuy nhiên, cách này sẽ tính:

$4 = 1 + 2 + 1$ và $4 = 1 + 1 + 2$ là hai cách khác nhau.

Cho nên, ta sẽ phải xem xét bổ sung một chiều nữa cho hàm $dp$ để tính cả thử tự của hàm này.

# 3. Lời giải chi tiết

Gọi $dp(i, j)$ là số cách để tạo ra đồng tiền mệnh giá $j$, khi ta chỉ sử dụng các đồng tiền với mệnh giá $coins[0]$ đến $coins[i]$.

Khi đó, ta có $dp(i, j) = \sum_{k = 0}^{j / coins[i]} dp(i - 1, j - k * coins[i])$.

Hoặc, để đảm bảo độ phức tạp, ta có thể viết lại thành:

$dp(i, j) = dp(i - 1, j) + dp(i, j - coins[i])$.

### Độ phức tạp thuật toán

Thời gian: $O(n * k)$ (do công thức tính cho mỗi ô nhớ là $O(1)$).

Bộ nhớ mở rộng: $O(n * k)$.

# 4. Kết luận & Gợi ý mở rộng

Đây là một bài cơ bản, và đã nằm trong chuyên đề DP của CLB. Các bạn có thể tham khảo thêm các bài toán sau:

[322. Coin Change](https://leetcode.com/problems/coin-change/)
[2218. Maximum Value of K Coins From Piles](https://leetcode.com/problems/maximum-value-of-k-coins-from-piles/)