1、整数拆分
题目描述
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
示例 1:
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
提示:
2 <= n <= 58
代码
class Solution {
public:
int integerBreak(int n) {
int dp[n+1];
memset(dp,0,sizeof(dp));//初始化,dp[1]与1做比较,d[i]首次取max用到
dp[2]=1;
for(int i=3;i<=n;i++){
int mid=i/2;
for(int j=1;j<=mid;j++){
int y=i-j;
int fst=max(j,dp[j]);
int scd=max(y,dp[y]);
dp[i]=max(dp[i],fst*scd);
}
}
return dp[n];
}
};
总结
做本题时把2到10的整数拆分列出来
2=1+1;
3=1+2;
4=1+3,4=2+2;
...
把一个整数拆成两个,这两个数要不要拆取决于拆分后结果是否大于本数,比如3=1+2,1不能拆,2>dp[2]也不能拆,所以dp[3] =1✖2=2;再比如4,4=1+3,1不能拆,3>dp[3]也不拆,dp[4]=1✖3=3,4=2+2,2>dp[2],所以2不拆,dp[4]更新为2✖2=4;其他数类似。
链接: 343. 整数拆分
2、不同的二叉搜索树
题目描述
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
输入:n = 3
输出:5
图片:
示例 2:
输入:n = 1
输出:1
提示:
1 <= n <= 19
代码
class Solution {
public:
int numTrees(int n) {
int dp[n+1];
memset(dp,0,sizeof(dp));
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];
}
}
return dp[n];
}
};
总结
这个题不太会…,看了题解才明白的。要注意节点数为1,2,3的二叉树之间的关系,找出规律。比如节点数为3时,1、2、3分别为头节点,1为头节点时比1小的无,比1大的有2、3,则dp[3]+=dp[0]✖dp[2],2为头结点时,比2小的为1,比2大的为3,dp[3]+=dp[1]✖dp[1],3为头结点时,比3小的有1、2,比3大的无,则dp[3]+=dp[2]✖dp[0]。
链接: 96. 不同的二叉搜索树