动态规划解决整数拆分问题

代码随想录链接:代码随想录

思路:

(1).确定dp数组的含义:

dpi:分拆数字i,可以得到的最大乘积为dpi

(2).确定递推公式:

dpi最大乘积是怎么得到:

其实可以从1遍历j,然后有两种渠道得到dpi.

一个是**j * (i - j)**直接相乘。

一个是j * dpi - j ,相当于是拆分(i - j)

**因此递推公式为:**dpi = max(dpi, max((i - j) * j, dpi - j * j))

注意这里在确定dpi时从1到i遍历j时更新dpi需要比较三个内容,分别是原始的dpi,j*(i-j)以及j*dpi-j,取这三个数的最大值更新dpi

(3).初始化dp数组:

严格从dpi的定义来说,dp0 dp1 就不应该初始化,也就是没有意义的数值

只初始化dp2 = 1,从dpi的定义来说,拆分数字2,得到的最大乘积是1,这个没有任何异议

(4).确定遍历顺序:

遍历i一定是从前向后遍历,先有dpi - j再有dpi

枚举j的时候,是从1开始的,从0开始的话,那么让拆分一个数拆个0,求最大乘积就没有意义

j的结束条件是 j < i - 1 ,其实 j < i 也是可以的

但是j的遍历只需要遍历到i/2(包含)就可以,后面就没有必要遍历

Java代码:

java 复制代码
class Solution {
    public int integerBreak(int n) {
        //dp[i] 为正整数 i 拆分后的结果的最大乘积
        int[] dp = new int[n+1];
        dp[2] = 1;
        for(int i = 3; i <= n; i++) {
            for(int j = 1; j <= i/2; j++) {
                // 这里的 j 其实最大值为 i-j,再大只不过是重复而已,
                //并且,在本题中,我们分析 dp[0], dp[1]都是无意义的,
                //j 最大到 i-j,就不会用到 dp[0]与dp[1]
                dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));
                // j * (i - j) 是单纯的把整数 i 拆分为两个数 也就是 i,i-j ,再相乘
                //而j * dp[i - j]是将 i 拆分成两个以及两个以上的个数,再相乘。
            }
        }
        return dp[n];
    }
}
相关推荐
郑州光合科技余经理38 分钟前
代驾系统架构拆解:订单链路、权限组织与私有化源码交付
开发语言·后端·算法·架构·系统架构·uni-app·php
To_OC3 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode
码哥DFS4 小时前
二叉树的直径
开发语言·javascript·算法
营养充电站6 小时前
KMP全栈开发:从Android到AI Agent的技术演进与实践
人工智能·算法·docker·jupyter
技术小黑7 小时前
RNN算法实战系列05 | 天气预测
人工智能·rnn·算法
Ivanqhz9 小时前
php8 use-def链
算法·php
evans在进步10 小时前
LeetCode 189 轮转数组:三次反转原地解决,图解 Java 实现
java·算法·leetcode
歌_顿10 小时前
Drawing_To_Model
算法
龍德明宇10 小时前
AI不会疼-龍德明宇
人工智能·算法·大语言模型llm·负主体性·ai存在论