class Solution {
public:
int integerBreak(int n) {
/*1.
确定dp数组(dp table)以及下标的含义:
dp[i]:分拆数字i,可以得到的最⼤乘积为dp[i]。
2. 确定递推公式
dp[i] = max(现有dp[i],dp[i-j]*j,(i-j)*j)
3. dp数组如何初始化:只有dp[2]需要初始化
4. 确定遍历顺序:从3到n
5. 举例推导dp数组*/
vector<int> dp(n+1);
dp[2] = 1;
for(int i = 3; i <= n ; ++i)
{
for(int j = 1; j <= i - 1; ++j)
{
dp[i] = max(dp[i],max(j*dp[i-j],j*(i-j)));
}
}
return dp[n];
}
};
这一题做得十分痛苦,好久没做动态规划。
①dp(n+1):0~n,要求dp[n]自然是n+1个元素
②初始化:dp[2]可分解为1*1=1
③动态规划就是把所有值遍历求出来,再返回所需要的
④从i=3开始,开始算dp[i]
⑤最让人头疼的递推公式。
首先,j的范围:j肯定是从1开始,因为dp[i]是可以分为1和i-1的;其次,j的上界:j是可以到达i-1的,但是这样就会拆出来一个1,导致dp[i]=dp[i-1],所以如果能证明dp[i]始终>dp[i-1]就可以把等号去掉,此处我没去掉;能否进一步变成i/2这种上界:不能,因为拆出来的j有可能就是i-1这种值;最后,递推公式:max(现在的值(vector初始值已经设为0,故可直接用);拆出来的j×dp[i-j];拆出来的j直接乘(i-j));为什么不能直接使用max(3个参数):C++不支持,只能两两比较。
本题还是不太熟悉,今天晚上看了一些面经有些绷不住,压抑。