心得
- 拿到题目瞎想,感觉相等的数值乘积应该最大,其实应该是拆分的时候,尽可能当前个数情况下,每个值相等,当时想的是平方根之后近可能靠近这个值,显然存在问题,本题确实存在数学优化解,而是尽可能拆分3的倍数,余下4或者都是3,不要想当然;应该从迭代角度,看看能够拆分老老实实迭代求加
题解
- 确定好dp数字含义,固定迭代处,拆分情况分别讨论即可,注意j的情况无需再拆分,在迭代过程中已经包含拆分过程,同时拆分求方案最值,此外优化了拆分的各值相等情况的计算量,在此处才是想的优化点
// 时间O(N^2),空间O(N)
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n + 1)
dp[2] = 1
for (int i = 3
for (int j = 1
dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
}
}
return dp[n]
}
}
// 贪心,时间O(N) 空间(1)
class Solution {
public:
int integerBreak(int n) {
if (n == 2) return 1
if (n == 3) return 2
if (n == 4) return 4
int result = 1
while (n > 4) {
result *= 3
n -= 3
}
result *= n
return result
}
}
心得
- 递推公式推错,算的是(n-1) *2 + 1,尤其是代入3的时候,这时候应该考虑1结点的时候能够覆盖,这样递推公式取决前两个状态,毕竟mid题目,只和前一个相关太牵强
- 最本质的办法还是从根节点入手,自己想的是上一种形态入手每个都可以首位插入,然后外加一种特殊情况,想的复杂了
题解
- 注意递推公式推理,从根节点入手,跟前两种状态相关,注意迭代顺序
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1, 0)
dp[0] = 1
for (int i = 1
for (int j = 1
dp[i] += dp[j - 1] * dp[i - j]
}
}
return dp[n]
}
}