动态规划-拆分数字

LeetCode链接

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

示例 1:

输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2:

输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

提示:

  • 2 <= n <= 58

解题思路:

动态规划五步曲

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

1.确定dp数组以及下标的含义

我们的目标是求分解数字的成绩的最大和,所以,dp[i]存储的应该是数字i拆分的数字成绩的最大值

2.确定递推公式

对于dp[i],即分解数字i得到最大乘积,如果分为两个数,用j从1开始遍历,乘积为(i-j)*j

或者拆分为多个数,这里就要想到用dp[i-j]*j,dp[i-j]就是将一个数拆分为两个及两个以上

求出这两个成绩之前的最大值,即max(dp[i-j]*j,(i-j)*j)

dp[i] = max(dp[i],max(dp[i-j]*j,(i-j)*j)

3.dp数组的初始化

这里的初始化,dp[0]为0,dp[1]也为0,直到dp[2]为1 * 1  = 1

4.确定遍历顺序

如果i < 3,其实就没有遍历的必要了,所以i从3开始遍历,

j则从1开始,到i-1,如果是到i,则会出现i-j为1,任何正数乘1都是1,所以没有遍历的必要

5.举例推导dp数组

for(int i = 3;i <= n;i++)
{
  for(int j = 1;j < i - 1;i++)
  {
    dp[i] = max(dp[i],max((i-j)*j),dp[i-j]*j);
  }              
}

给出LeetCode的代码

复制代码
class Solution {
public:
    int integerBreak(int n) {
        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*(i-j),j*dp[i-j]));
            }
        }
        return dp[n];
    }
};
复制代码

 

posted @   写在风中的信  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示