leetcode343—整数拆分原题链接
题意简述
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。
解题分析
dp[i]: 正整数i能获得的乘积最大化
分析:
很容易想到这个dp[i]=max(dp[i],j * dp[i-j]),
问题是dp[2]=1,dp[3]=2,dp[4]=4,都是不符合这个规律
的...当然,可以枚举这些特殊情况处理.
认真的分解几个数发现,只要i>=4,i获得乘积最大化的
时候其一定是分解成2,3相加.所以这里就想到另一个状态转
移方程:dp[i]=max(2*dp[i-2],3*dp[i-3])
状态转移方程:
dp[i]=max(2*dp[i-2],3*dp[i-3])
复杂度分析:
时间复杂度:O(n);
空间复杂度:O(n).
参考代码
class Solution {
public int integerBreak(int n) {
if(n == 2) return 1;
if(n == 3) return 2;
int[] dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
for(int i = 4; i < n + 1; i++) {
dp[i] = Math.max(2 * dp[i - 2], 3 * dp[i - 3]);
}
return dp[n];
}
}
func integerBreak(n int) int {
if n == 2 {
return 1
}
if n == 3 {
return 2
}
var dp [60]int
dp[1], dp[2], dp[3] = 1, 2, 3
for i := 4; i <= n; i++ {
dp[i] = max(2 * dp[i - 2],3 * dp[i - 3])
}
return dp[n]
}
func max(a,b int) int {
if a > b {
return a
} else {
return b
}
}