518. 零钱兑换 II
题目链接:518. 零钱兑换 II
文档讲解:代码随想录
状态:不会
思路:
和494.目标和类似,这题属于组合问题,当我们有一个硬币coin时,对于每个金额j,通过添加这个硬币,我们可以把凑成金额j-coin的所有方法数加到凑成金额j的方法数中。这是因为每一种凑成 j-coin 的方法,加上硬币coin,都变成了一种凑成j的方法。
注意:
- dp[j] 就是所有的dp[j - coins[i]](考虑coins[i]的情况)相加。
- 要考虑dp[0]=1
- j>=coins[i]
题解:
public int change(int amount, int[] coins) {int[] dp = new int[amount + 1]; // 创建一个长度为 amount + 1 的数组 dp,用于存储每个金额的组合数dp[0] = 1; // 初始化 dp[0] 为 1,因为组成金额为 0 的唯一方法是使用 0 个硬币for (int coin : coins) { // 遍历每个硬币// for (int j = 1; j <= amount; j++) {// if (j >= coin) {// dp[j] += dp[j - coin]; // }// }for (int j = coin; j <= amount; j++) { // 从当前硬币的面值开始遍历到目标金额dp[j] += dp[j - coin]; // 更新 dp[j],将当前硬币加入组合中}}return dp[amount]; // 返回组成目标金额的组合数}
377. 组合总和 Ⅳ
题目链接:377. 组合总和 Ⅳ
文档讲解:代码随想录
状态:还行
思路:这题属于排列问题,需要先遍历target再遍历nums。
题解:
public int combinationSum4(int[] nums, int target) {int[] dp = new int[target + 1];dp[0] = 1;for (int j = 1; j <= target; j++) {for (int i = 0; i < nums.length; i++) {if (j >= nums[i]) {dp[j] += dp[j - nums[i]];}}System.out.println(Arrays.toString(dp));}return dp[target];}
70. 爬楼梯 (进阶)
题目链接: 70. 爬楼梯 (进阶)
文档讲解:代码随想录
状态:还不熟练
思路:其实就是排列问题,但是要注意步数不能超过要爬的台阶数
题解:
public void climb() {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();int[] dp = new int[n + 1];dp[0] = 1;for (int i = 1; i <= n; i++) {for (int j = 0; j <= m; j++) {if (j <= i) {//表示步数不能超过要爬的台阶数dp[i] += dp[i - j];}}
// System.out.println(Arrays.toString(dp));}System.out.println(dp[n]);}