leetcode343 整数拆分 && 不同的二叉搜索树

在这里插入图片描述

一看题目就知道当前状态肯定是依赖于之前的状态的,故需要使用动态规划。

动态规划五部曲:

  1. 确定dp数组及其下标的含义
    dp[i]为第i个数字的最大乘积
  2. 初始化dp数组
    数字0和1的拆分是没有意义的,故直接只初始化dp[2] = 1
  3. 确定递推公式
    dp[i]可以由 j * (i - j) 以及j * dp[i-j]推导而来,这里i的取值为 3 <= i <= n, j的取值为 1<=j < i-1,可以保证i - j > 1,即 (i - j)最小取2
    故递推公式为dp[i] = max(dp[i], j * dp[i-j]), j * i-j)
  4. 确定递推顺序
    由递推公式可知,dp[i]是由dp[i - j]递推而来,而i大于i-j, 故从前向后递推
  5. 模拟dp[i]数组

代码:

class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n+1, 0);
        //dp[0]和dp[1]没有意义
        dp[2] = 1;
//递推公式:
//dp[i] = max(dp[i], j * (i-j), j * dp[i-j])
        for(int i = 3; i <= n; i++){
            for(int j = 1; j < i-1; j++){
                dp[i] = max(dp[i], max(j * dp[i-j], j * (i-j)));
            }
        }

        return dp[n];

    }
};

在这里插入图片描述

思路:由1个结点组成的二叉搜索树有1种 dp[1] = 1,2个结点的有2种 dp[2] = 2。初始化dp[0] = 1
设dp[i]为由i个结点组成的二叉搜索树有多少种。
则由观察由3个结点组成的二叉树可知:
dp[3] = dp[0] * dp[2] + dp[1] * dp[1] + dp[2] * dp[0]
= 1 * 2 + 1 * 1 + 2 * 1 = 5
故dp[3]可由dp[1]和dp[2]推出来,即当前状态与之前的状态有关,或者说当前状态可以由之前的状态推导而来,用动态规划!

class Solution {
public:
    int numTrees(int n) {
        vector<int> dp(n+1);
        dp[0] = 1;
        dp[1] = 1;

        for(int i = 2; i <= n; i++){
            for(int j = 1; j <= i; j++){
                dp[i] += dp[j-1] * dp[i - j];
            }
        }

        return dp[n];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值