DFS 状态定义:dfs(i, j) 表示仅使用前 i 种硬币(下标范围 [0…i]), 刚好凑出总金额为 j 时,所需要的最少硬币数量。 对于第 i 种硬币,我们可以: 1. 不选它:直接看前 i-1 种硬币,状态转移为 dfs(i-1, j) 2. 选它:因为硬币数量无限,我们还可以继续选第 i 种硬币(下标 i 不变),状态转移为 dfs(i, j - coins[i]) + 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
List<Integer> path = new ArrayList<>();
int[][] m;

/**
* DFS 状态定义:dfs(i, j)
* 表示仅使用前 i 种硬币(下标范围 [0...i]),
* 刚好凑出总金额为 j 时,所需要的最少硬币数量。
*
* 对于第 i 种硬币,我们可以:
* 1. 不选它:直接看前 i-1 种硬币,状态转移为 dfs(i-1, j)
* 2. 选它:因为硬币数量无限,我们还可以继续选第 i 种硬币(下标 i 不变),状态转移为 dfs(i, j - coins[i]) + 1
*/
public int coinChange(int[] coins, int amount) {
m = new int[coins.length][amount+1];
for (int[] arr : m) {
Arrays.fill(arr, -1);
}
int ans = dfs(coins, coins.length - 1, amount);
return ans >= Integer.MAX_VALUE / 2 ? -1 : ans;
}

private int dfs(int[] coins, int i, int amount) {
if (i < 0) {
if (amount == 0) return 0;
return Integer.MAX_VALUE / 2;
}

if (m[i][amount] != -1) return m[i][amount];
// 使用这个coin
if (coins[i] > amount) {
return m[i][amount] = dfs(coins, i-1, amount);
}
int use = dfs(coins, i, amount - coins[i]) + 1;

// 不用这个coin
int unuse = dfs(coins, i-1, amount);
return m[i][amount] = Math.min(unuse, use);
}
}

Comments
Recent Posts
Untitled
Categories
Tags
Website Info
Article Count :
2
Total Word Count :
1.6k
Unique Visitors :
Page Views :
Last Update :