343. 整数拆分
class Solution {
// 解决这一类问题的入手点就是从小数字进行模拟: 比如 n = 2, 2 = 1 + 1, => n = 3, 2 + 1 = 3到这里地方再思考
// 2要不要拆分呢, 取决于2本身了, 这样就将问题 3 转化到问题 2(子问题)
// n = 4, n = 2 + 2 (1) 或者 n = 1 + 4 (2) , 那么划分(1), 还是划分 (2) 取决于谁划分的乘积更大
// 因此, for(int i = 1; i<= n / 2, i++){}按这种方式遍历不同划分取决于 i * (j-i) 的最大, 但是(j - i) 如何划分或是不需要划分, 这就形成了递归公式。
// 定义dp[i]: 表示数字i 划分后的最大乘积, 则 dp[j - i] 就是前一个数字 j - i划分的最大乘积
// 则 max (j - i, dp[j - i]);// 如果j - i更大, 代表已经不需要继续划分。
// 至此, 代码就能写出来了
// 动态规划就形成了类似数学归纳法的思考过程
public int integerBreak(int n) {
int[] dp = new int[n + 1];// 定义划分数字i所得乘积的最大
dp[2] = 1;
for (int i = 3; i <= n; i++) {
// 遍历不同的两个数字的划分:返回划分和不划分的最大值, 在与当前值对比返回最大值.
for (int j = 1; j < i; j ++){
dp[i] = Math.max(dp[i], j * Math.max((i - j), dp[i - j]));
}
}
return dp[n];
}
}