动态规划相关

力扣509 斐波那契数列 完全递归解法 / 设置备忘录减少递归次数解法 都是 自顶向下

public int fib(int n) {
        /*
         * if(n<2){
         * return n;
         * }
         * else{
         * return fib(n-1) + fib(n-2);
         * }
         */

        int[] memo = new int[n + 1];
        // 0-n 有效 存储计算出出来的 fib(n)
        return dp(memo, n);
    }

    public int dp(int[] memo, int n) {
        if (n == 1 || n == 0) {
            return n;
        } else {
            if (memo[n] != 0) {
                // 已经计算过的直接return
                return memo[n];
            } else {
                memo[n] = dp(memo, n - 1) + dp(memo, n - 2);
                return memo[n];
            }
        }
    }

力扣 509 斐波那契数列 动态规划 自底向上

public int fib(int n) {
        if(n==0 || n==1){
            return n;
        }
        int temp1 = 0;
        int temp2 = 1;
        int tempR = 0;
        for(int i=2;i<=n;i++){
            tempR = temp1+temp2;
            temp1 = temp2;
            temp2 = tempR;
        }
        return tempR;
    }

力扣322 零钱兑换 递归 !!!!!

  int[] memo;

    public int coinChange(int[] coins, int amount) {
        memo = new int[amount + 1];
        Arrays.fill(memo, -666);
        return dp(coins, amount);
    }

    // 定义:要凑出金额 n,至少要 dp(coins, n) 个硬币
    int dp(int[] coins, int n) {
        // 做选择,选择需要硬币最少的那个结果
        if (n == 0)
            return 0;
        if (n < 0)
            return -1;

        if (memo[n] != -666) {
        // 该子问题已经计算过了 直接返回结果
            return memo[n];
        } else {
            int min = Integer.MAX_VALUE;
            for (int coin : coins) {
                int subProblem = 0;
                subProblem = dp(coins, n - coin);
                // 若 n-coin>=0 则在dp 函数中的return之前已经完成对memo的更新
                if (subProblem == -1) {
                // 子问题无解 则跳过
                    continue;
                } else {
                // 更新min 子问题的解+1
                    min = Math.min(subProblem + 1, min);
                }

            }
            memo[n] = Integer.MAX_VALUE > min ? min : -1;
            return memo[n];
        }
    }

力扣322 零钱兑换 动态规划!!!!!

在这里插入图片描述

int[] dp;

    public int coinChange(int[] coins, int amount) {
        dp = new int[amount + 1];
        Arrays.fill(dp, amount + 1);
        // dp数组值 应该为 -1 - amount
        // 无解-1
        // 有解则最少0个硬币 最多amount个硬币

        dp[0] = 0;

        for (int i = 1; i < amount + 1; i++) {
            for (int coin : coins) {
                if (i - coin < 0) {
                    continue;
                } else {
                    // 已经算到 i 了 则 i-coin 已经算完了
                    int sub = dp[i - coin] + 1;
                    // 如果其实 dp[i-coin] 没有被更新计算过 则 dp[i] 依然保持amount+1
                    // 相当于dp[i] 也没有被计算更新
                    dp[i] = dp[i] > sub ? sub : dp[i];
                    // 保证为dp[i]更新最小的 
                }
            }
        }
        return dp[amount] < amount+1 ? dp[amount] : -1;
        // 如果 dp[amount]<amount+1 则说明取到了最少的 硬币数目
        // 否则 说明 没有找到解返回-1
   }
posted @ 2024-04-21 22:52  在天边偷看小天使  阅读(8)  评论(0)    收藏  举报  来源