整数拆分
根据题意,一个整数可以被拆分成两个以上的数,求拆分之后能获得的最大乘积。
-
首先分析dp[i]数组的含义:dp[i]应该表示整数i拆分之后的最大乘积
-
dp数组定义:我们求整数i的最大乘积的思路是使用两层for循环,从1开始拆分,遍历所有的可能性,举例来说当n=6,逐一拆分成(1,5)(2,4)(3,3),求其乘积最大值。所以dp数组定义为
dp[i] = Math.max(dp[i],Math.max(j * (i - j),j * dp[i - j]));j*(i - j)表示将整数拆分成两个数,j * dp[i - j]表示将整数拆分成两个以上的数,dp[i]表示求循环过程中dp[i]的最大值
-
dp数组初始化,显然dp[0],dp[1]拆分无意义,所以不进行初始化定义,定义dp[2]=1
-
遍历方向,显然是从左往右遍历
可以看到j遍历到i/2的位置就停止遍历了,这是因为
如果m表示能实现整数乘积最大化的拆分的乘数的数量, 最大值一般出现在n/m值附近,比如n=10,最大值是3*3*4,在10/3附近, 所以遍历j的时候,遍历到m=2,即n/2的位置就可以了,即将整数拆分成两个数,剩下的继续遍历的接结果肯定没有中间位置乘积大
不同的二叉搜索树
可以观察一下n=3的时候的树的规则,当头节点值为1,只有右子树,右子树的规则和n=2时二叉搜索树的形态相同,头节点值为2,左右各有一个子树,规则和n=1时二叉搜索树的形态相同,同理n=3时的情况。
1.dp[i]定义:i个节点形成的子树的个数
2.dp[i] = dp[i-j-1] * dp[j],i表示节点总数,j表示左子树节点数量
3.dp[0]无意义,后面相乘的时候应该作为1,所以定义为1;dp[1]只有一种子树
4.遍历方向:从左往右