代码随想录算法训练营29期|day50 任务以及具体任务

第九章 动态规划part07

  •  70. 爬楼梯 (进阶)代码随想录算法训练营29期|day50 任务以及具体任务_第1张图片
    import java.util.Scanner;
    class climbStairs{
        public static void main(String [] args){
            Scanner sc = new Scanner(System.in);
            int m, n;
            while (sc.hasNextInt()) {
                // 从键盘输入参数,中间用空格隔开
                n = sc.nextInt();
                m = sc.nextInt();
    
                // 求排列问题,先遍历背包再遍历物品
                int[] dp = new int[n + 1];
                dp[0] = 1;
                for (int j = 1; j <= n; j++) {
                    for (int i = 1; i <= m; i++) {
                        if (j - i >= 0) dp[j] += dp[j - i];
                    }
                }
                System.out.println(dp[n]);
            }
        }
    }

    思路:该题和背包问题一样,n为背包大小,1到m为物品的大小,要求装满背包有几种方法,而且是可以重复取物品。

  •  322. 零钱兑换 代码随想录算法训练营29期|day50 任务以及具体任务_第2张图片
    class Solution {
        public int coinChange(int[] coins, int amount) {
            int max = Integer.MAX_VALUE;
            int[] dp = new int[amount + 1];
            //初始化dp数组为最大值
            for (int j = 0; j < dp.length; j++) {
                dp[j] = max;
            }
            //当金额为0时需要的硬币数目为0
            dp[0] = 0;
            for (int i = 0; i < coins.length; i++) {
                //正序遍历:完全背包每个硬币可以选择多次
                for (int j = coins[i]; j <= amount; j++) {
                    //只有dp[j-coins[i]]不是初始最大值时,该位才有选择的必要
                    if (dp[j - coins[i]] != max) {
                        //选择硬币数目最小的情况
                        dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
                    }
                }
            }
            return dp[amount] == max ? -1 : dp[amount];
        }
    }

    思路:该题是完全背包问题,dp数组表示装满j需要的最少物品。该题不需要考虑组合或者排序,先遍历背包或者物品都可以。

  •  279.完全平方数代码随想录算法训练营29期|day50 任务以及具体任务_第3张图片
    class Solution {
        // 版本一,先遍历物品, 再遍历背包
        public int numSquares(int n) {
            int max = Integer.MAX_VALUE;
            int[] dp = new int[n + 1];
            //初始化
            for (int j = 0; j <= n; j++) {
                dp[j] = max;
            }
    	//如果不想要寫for-loop填充數組的話,也可以用JAVA內建的Arrays.fill()函數。
    	//Arrays.fill(dp, Integer.MAX_VALUE);
    	
            //当和为0时,组合的个数为0
            dp[0] = 0;
            // 遍历物品
            for (int i = 1; i * i <= n; i++) {
                // 遍历背包
                for (int j = i * i; j <= n; j++) {
                    //if (dp[j - i * i] != max) {
                        dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
                    //}
    		//不需要這個if statement,因爲在完全平方數這一題不會有"湊不成"的狀況發生( 一定可以用"1"來組成任何一個n),故comment掉這個if statement。
                }
            }
            return dp[n];
        }
    }
    
    class Solution {
        // 版本二, 先遍历背包, 再遍历物品
        public int numSquares(int n) {
            int max = Integer.MAX_VALUE;
            int[] dp = new int[n + 1];
            // 初始化
            for (int j = 0; j <= n; j++) {
                dp[j] = max;
            }
            // 当和为0时,组合的个数为0
            dp[0] = 0;
            // 遍历背包
            for (int j = 1; j <= n; j++) {
                // 遍历物品
                for (int i = 1; i * i <= j; i++) {
                    dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
                }
            }
            return dp[n];
        }
    }

    思路:这道题和上一题思路一样,都是要求最小组成数,只不过是物品发生了变化。

你可能感兴趣的:(算法,数据结构,leetcode,java,代码随想录)