343. 整数拆分
Preface
昨天没写是因为完全搞不懂题解和答案, 也是少有的结合DFS和动归的题目,个人感觉有点写大项目的意思,所以就看看就好了。。。
今天的题目,怎么说,也是动归的基本题目吧,但是还是那个问题,怎么找到动态转移方程是一个关键。
Solution
343. 整数拆分
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。
详细的推导过程可以去看reference部分,其实一个简单的想法,就是怎么样和前面的撤上关系,因为可能我们已经有了前面所有的除了n以外的最佳值,那么是不是就是说我们可以遍历之前的所有的值并且乘以当前遍历值与n的差值既可以找到最佳值。当然,因为我们可以最少两个正整数之和,所以在对比之前的最优解之前,也同步对比这个二分的乘积即可。
但是这样做很明显不是最优解,因为我们可能花了很多时间去探索不因该是最优解的部分,很重要的一点是,(详细去看reference的官解)在和n相差4以上其实就可以不用去探索了,因为这是浪费时间。
class Solution {
public:
int integerBreak(int n) {
if (n < 4)
return n - 1;
vector<int> dp(n + 1);
dp[2] = 1;
for (auto i = 3; i <=n; ++i)
{
dp[i] = max(max(2 * (i - 2), 2 * dp[i - 2]), max(3 * (i - 3), 3 * dp[i - 3]));
}
return dp[n];
}
};
当然,正如我之前所提到的,数学可以更好的解决这种数论问题。
详细还是去看看官解好了,这里不再赘述 (因为很难我自己写出来,写出来也没人家好,2333