动态规划解题思路以及和递归之间的关系

在这里插入图片描述
在这里插入图片描述

一.509.斐波那契数列

解题思路

第一种:(自顶向下)
直接使用原函数递归
会有重复计算的问题
第二种:(自顶向下)
在原有的第一种解法的基础上进行优化,即进行了备忘录操作避免了重复计算的问题
第三种:(自底向上)
使用dp数组

代码

class Solution {
    public int fib(int n) {
        if(n==0 || n==1){
            return n;
        }
        return fib(n-1)+fib(n-2);
    }
}

class Solution {
    public int fib(int n) {
        int[] note = new int[n+1];
        if(n<=0){
            return 0;
        }
        return searchFib(note,n);
    }
    public int searchFib(int[] note,int n){
        if (n==1 || n==2) return 1;
        if (note[n]!=0){
            return note[n];
        }
        note[n]=searchFib(note,n-1)+searchFib(note, n-2);
        return note[n];
    }
}

class Solution {
    public int fib(int n) {
        int[] nums = new int[2];
        nums[0]=0;
        nums[1]=1;
        if (n<=1){
            return nums[n];
        }
        for (int i=2;i<n;i++){
            int sum = nums[0]+nums[1];
            nums[0]=nums[1];
            nums[1]=sum;
        }
        return nums[0]+nums[1];
    }
}

二.322.零钱兑换问题

解题思路

第一种:
递归,有重复计算问题,会超时
第二种:
在第一种的基础上进行优化,使用笔记本剪枝,但是效率还是不高
第三种:dp动态规划

代码

class Solution {
    public int coinChange1(int[] coins, int amount) {
        if (amount<0) return -1;//递归的终止条件,说明兑换的方式不能够换出amount
        if (amount==0) return 0;
        int ans = Integer.MAX_VALUE,length=coins.length;
        for (int i=0;i<length;i++){
            int semple = coinChange1(coins,amount-coins[i]);
            if (semple==-1) continue;
            ans = Math.min(ans,semple+1);
        }
        return ans==Integer.MAX_VALUE?-1:ans;
    }
}

class Solution {
    int[] note;
    public int coinChange(int[] coins, int amount) {
        note = new int[amount+1];
        Arrays.fill(note,-999);
        return search(coins,amount);
    }
    public int search(int[] coins,int amount){
        if (amount<0) return -1;//递归的终止条件,说明兑换的方式不能够换出amount
        if (amount==0) return 0;
        if (note[amount]!=-999) return note[amount];
        int length = coins.length,res=Integer.MAX_VALUE;
        for (int i=0;i<length;i++){
            int semple = search(coins,amount-coins[i]);
            if (semple==-1) continue;
            res=Math.min(res,semple+1);
        }
        note[amount]=res==Integer.MAX_VALUE?-1:res;
        return note[amount];
    }
}

class Solution {
    public int coinChange(int[] coins, int amount) {
        /*
        dp数组的具体含义就是
        dp[2]=1
        说明凑齐两元在最好的情况下只需要一枚2元的硬币
        */
        //初始化dp数组
        int[] dp = new int[amount+1];
        Arrays.fill(dp,amount+1);
        //base case
        dp[0]=0;
        if (amount==0) return 0;
        if (amount<0) return -1;

        for (int i=0;i<amount+1;i++){
            for (int coin:coins){
                if (i-coin<0) continue;
                dp[i]=Math.min(dp[i],1+dp[i-coin]);
            }
        }
        return dp[amount]==amount+1?-1:dp[amount];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多维动态规划(MDP)是一种在多维状态空间中求解最优策略的算法。下面是解题思路的一般步骤: 1. 定义状态和动作:首先,需要明确问题的状态和可选的动作。将问题抽象成一个多维状态空间,并确定每个状态下可执行的动作。 2. 定义价值函数:为了评估每个状态的优劣,需要定义一个价值函数来衡量状态的价值。价值函数可以是累积奖励、期望回报等。 3. 定义转移函数:转移函数描述了状态之间的转换关系,即在执行某个动作后,当前状态如何转移到下一个状态。转移函数可以是确定性的或概率性的。 4. 构建动态规划表格:根据问题的状态空间和动作空间,构建一个多维表格。每个单元格代表一个状态,并记录该状态下执行不同动作所得到的价值。 5. 递归求解最优策略:从最后一个状态开始,根据动态规划的原理递归地计算每个状态的最优价值,并记录最优动作。通过向前逐步计算,可以得到整个状态空间下的最优策略。 6. 优化算法:对于复杂问题,可以采用一些优化技巧来减少计算量,如值迭代、策略迭代等。 需要注意的是,多维动态规划算法的实现可能会比较复杂,涉及到状态空间的遍历和动作选择等问题。因此,了解问题的特点和算法的原理非常重要。 希望这个解题思路能对你有所帮助!如果还有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值