算法随想Day36【动态规划】| LC343-整数拆分、LC96-不同的二叉搜索树

动态规划五部曲

  • 确定dp[i]的含义
  • dp递推公式
  • dp数组如何初始化
  • 确认dp数组遍历顺序
  • 打印dp数组,主要用于调试

LC343. 整数拆分

  1. dp[i]含义:数字 i 被拆解后的最大乘积
  2. 递推公式:对多组dp[i] * [i - j] 求最大值
  3. dp数组初始化:dp[1] = 1; dp[2] = 2; dp[3] = 3;
  4. 确认dp数组遍历顺序:从左往右

为了要初始化dp[2] = 2; dp[3] = 3 为这样,思路在注释中写得很清楚了

int integerBreak(int n)
{
    if (n == 2)  return 1;
    if (n == 3)  return 2;
    vector<int> dp(n + 1, 0);
    // dp[0] = 0;
    dp[1] = 1;
    ////比2和3大的数,在拆分成2或3的时候,因为2 < dp[2]
    ////3 < dp[3],所以干脆让dp[2] > dp[3]
    ////dp[i]数组代表数字i被拆解后的最大乘积
    ////而对4来说,刚好有4 = dp[4],所以其为dp[i] > i的临界i值
    dp[2] = 2;
    dp[3] = 3;

    for (int i = 4; i <= n; ++i)
    {
        int max = 0;
        for (int j = 1; j <= i / 2; ++j)
        {
            int temp = dp[j] * dp[i - j];
            if(temp > max)
            {
                max = temp;
            }
        }
        dp[i] = max;
    }

    return dp[n];
}

LC96. 不同的二叉搜索树

  1. dp[i]含义:数字i被拆解后的最大乘积
  2. 递推公式:对多组dp[j] * dp[i - 1 - j]求最大值
  3. dp数组初始化:dp[0] = 1;
  4. 确认dp数组遍历顺序:从左往右

这道题的状态推导比较直观,注意初始化dp[0] = 1;

int numTrees(int n)
{
    vector<int> dp(n + 1, 0);
    dp[0] = 1;  //不能初始化为0
    dp[1] = 1;
    dp[2] = 2;
    if (n <= 2)  return n;
    for (int i = 3; i <= n; ++i)
    {
        int sum = 0;
        for (int j = 0; j < i; ++j)
        {
            sum += dp[j] * dp[i - 1 - j];
        }
        dp[i] = sum;
    }
    return dp[n];
}
posted @ 2023-03-15 13:07  冥紫将  阅读(25)  评论(0)    收藏  举报