代码随想录算法训练营第三十二天| 343. 整数拆分 96.不同的二叉搜索树

 343. 整数拆分

要求:

将一个正数拆分成N个正整数,使得这N个正整数的乘机是最大的

思路:

DP数组:dp[n] N 的时候,它的乘机最大值

注意:

不是i*dp[n-i]就是最大值,因为如果用dp就证明要开始拆分了,如果我不拆分,就是用的这两个数的话,那么就是单纯的 i* (n-i)

代码:

 1 // 要求:将N 拆分成 K个正整数的和(K》=2) 并让这些整数的乘机最大化
 2 // 
 3 // 可能的思路:数在这个范围内,同时相差最小
 4 // 难点:如何求的乘机最大化
 5 // 
 6 // 动态规划的思路:
 7 //    dp的定义:dp[n] N个数它的乘机最大化
 8 // 递推公式分为两种:
 9 //    1,两个数之间取最大值 : i *(n-i)
10 //    2,三个及以上去的最大值 : i * dp[n-i]
11 //
12 int integerBreak(int n) {
13     vector<int> dp(n+1, 0);
14     if (n < 2) return dp[n];
15 
16     dp[2] = 1;
17     for (int i = 3; i < dp.size(); i++)
18     {
19         
20         for (int j = 0; j <= i; j++)
21         {
22             //两个值的情况
23             int cur1 = j * (i - j);
24             int cur2 = j * dp[i - j];
25 
26             dp[i] = max(dp[i], max(cur1, cur2));
27         }
28     }
29 
30     return dp[n];
31 }

 96.不同的二叉搜索树 

思路:

1,先画图,虽然会发现有一部分是在之前的类加上去的,但是我们需要想的细一点

2, 分成左右孩子,这两种情况,如果左边*右边,然后计算左边有多少个,右边有多少个

代码:

 1 int numTrees(int n) {
 2     vector<int>dp(n + 1, 0);
 3     if (n == 0) return 0;
 4     if (n == 1) return 1;
 5     if (n == 2) return 2;
 6     dp[1] = 1;
 7     dp[2] = 2;
 8 
 9     for (int i = 3; i <= n; i++)
10     {
11         //j是顶点
12         for (int j = 1; j <= i; j++)
13         {
14             dp[i] += (dp[j - 1] == 0 ? 1 : dp[j - 1]) * (dp[i - j] == 0 ? 1 : dp[i - j]);
15         }
16     }
17 
18     return dp[n];
19 }

 

posted @ 2023-07-17 09:46  博二爷  阅读(6)  评论(0编辑  收藏  举报