代码随想录day40:动态规划part03

343.正数拆分

  1. dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。
  2. dp[i]=max(dp[i],max(j*(i-j),dp[i-j]*j)); 是d[i-j]而不是d[j]。因为d[j]已经从1到j遍历拆分了
  3. dp[2] = 1。0,1无法拆分
  4. 从前向后,且第二层循环可以优化j
  5. 时间复杂度:O(n^2)  空间复杂度:O(n)
    
class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n+1,0);
        dp[2]=1;
        for(int i=3;i<=n;i++){
            for(int j=1;j<i-1;j++){
                dp[i]=max(dp[i],max(j*(i-j),dp[j]*(i-j)));
            }
        }
        return dp[n];
    }
};

96.不同的二叉搜索树

dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量
元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量;
元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量;
元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量;

class Solution {
public:
    int numTrees(int n) {
        vector<int> dp(n+1,0);
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<=n;i++){
            for(int j=0;j<i;j++){
                dp[i]+=dp[j]*dp[i-j-1];//for(j=1;j<=n;j++)dp[i] += dp[j - 1] * dp[i - j];
            }
        }
        return dp[n];
    }
};

你可能感兴趣的:(动态规划,算法,数据结构)