Dynamic_Programming

博客围绕动态规划展开,介绍小偷背包问题中贪心与动态规划的适用情况,指出动态规划适用于相互离散且独立的问题。还给出实例,对比了动态规划和递归的应用场景,并对LeetCode 486和464题进行分析,包括证明和分析过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 小偷背包问题

偷商品的一部分, 不能用dp, 只能用贪心(dp, 要么考虑拿走整件商品, 要么不拿, 偷走的商品不可分割性)

2. 动态规划只能解决的问题: 相互离散且独立

3. 实例(代替递归, 把结果记录下来, )

参考文献
题目:
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:

输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

public int getAns(int n){
        int[] dp = new int[10];
        dp[0] = 1;
        dp[1] = 1;

        for (int i=2; i<=n; i++ ){
            for (int j=0; j<i; j++){ //root的左子树的节点数目
                dp[i] += dp[j] * dp[i-1-j];
            }
        }

        return dp[n];
    }
  1. 递归解法
class Solution:
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 0 or n == 1:
            return 1
        res = 0
        
        for j in range(1, n + 1):
            res += self.numTrees(j-1) * self.numTrees(n-j)
        
        return res

4. 动态规划不如递归的应用场景

参考文献, 翻到最下面就能看到不如的场景

5 leetcode 486

参考解答

证明过程

  对于奇数个数字的数组,利用动态规划(dynamic programming)计算。 首先证明最优子结构性质。对于数组[1…n]中的子数组[i…j],假设玩家1在子数组[i…j]中的拿法是最优的,即拿的分数比玩家2多出最多。假设玩家1拿了i,则[i+1…j]中玩家1拿的方法也一定是最优的。利用反证法证明:如果玩家1在[i+1…j]中有更优的拿法,即玩家1在[i+1…j]可以拿到更多的分数,则玩家在[i…j]中拿到的分数就会比假设的最优拿法拿到的分数更多,显然矛盾。如果玩家1拿了j,同理可证矛盾。 所以当前问题的最优解包含的子问题的解一定也是子问题的最优解。

分析过程

  对于只有一个数字的子数组,即i=j,dp[i][i] = num[i],因为玩家1先手拿了这一个分数,玩家2就没得拿了,所以是最优拿法。 对于两个数字的子数组,即j-i=1,dp[i][j]=abs(num[i]-num[j]),玩家1先手拿两个数中大的一个,所以玩家1一定比玩家2多两个数字差的绝对值,为最优拿法。 对于j-i>1的子数组,如果玩家1先手拿了i,则玩家1手里有num[i]分,则玩家2一定会按照[i+1…j]这个子数组中的最优拿法去拿,于是玩家2此时手里相当于有dp[i+1][j]分,于是玩家1比玩家2多num[i]-dp[i+1][j]分。如果玩家1先手拿了j,则玩家1手里有num[j]分,则玩家2一定会按照[i…j-1]这个子数组中的最优拿法去拿,于是玩家2此时手里相当于有dp[i][j-1]分,于是玩家1比玩家2多num[j]-dp[i][j-1]分。数组的填充方向是从下往上,从左到右,最后填充的是dp[1][n]。

leetocode 464

通俗解释参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值