算法随想Day36【动态规划】| LC343-整数拆分、LC96-不同的二叉搜索树
动态规划五部曲
- 确定dp[i]的含义
- dp递推公式
- dp数组如何初始化
- 确认dp数组遍历顺序
- 打印dp数组,主要用于调试
LC343. 整数拆分
- dp[i]含义:数字 i 被拆解后的最大乘积
- 递推公式:对多组dp[i] * [i - j] 求最大值
- dp数组初始化:dp[1] = 1; dp[2] = 2; dp[3] = 3;
- 确认dp数组遍历顺序:从左往右
为了要初始化dp[2] = 2; dp[3] = 3 为这样,思路在注释中写得很清楚了
int integerBreak(int n)
{
if (n == 2) return 1;
if (n == 3) return 2;
vector<int> dp(n + 1, 0);
// dp[0] = 0;
dp[1] = 1;
////比2和3大的数,在拆分成2或3的时候,因为2 < dp[2]
////3 < dp[3],所以干脆让dp[2] > dp[3]
////dp[i]数组代表数字i被拆解后的最大乘积
////而对4来说,刚好有4 = dp[4],所以其为dp[i] > i的临界i值
dp[2] = 2;
dp[3] = 3;
for (int i = 4; i <= n; ++i)
{
int max = 0;
for (int j = 1; j <= i / 2; ++j)
{
int temp = dp[j] * dp[i - j];
if(temp > max)
{
max = temp;
}
}
dp[i] = max;
}
return dp[n];
}
LC96. 不同的二叉搜索树
- dp[i]含义:数字i被拆解后的最大乘积
- 递推公式:对多组dp[j] * dp[i - 1 - j]求最大值
- dp数组初始化:dp[0] = 1;
- 确认dp数组遍历顺序:从左往右
这道题的状态推导比较直观,注意初始化dp[0] = 1;
int numTrees(int n)
{
vector<int> dp(n + 1, 0);
dp[0] = 1; //不能初始化为0
dp[1] = 1;
dp[2] = 2;
if (n <= 2) return n;
for (int i = 3; i <= n; ++i)
{
int sum = 0;
for (int j = 0; j < i; ++j)
{
sum += dp[j] * dp[i - 1 - j];
}
dp[i] = sum;
}
return dp[n];
}

浙公网安备 33010602011771号