dp的含义表示:从前i个数中挑选,满足和为j的最大乘积为多少。由于是乘积所以dp初始均为1。i为2开始是因为从1开始挑选,j为2开始应为有效数字是从2开始。 进一步空间优化,应为dp[i][j]只与其相邻的状态有关。

// 思路初探:将本题转化成完全背包问题。
// 完全背包问题不用塞满背包,而本题“必须塞满背包”,如何转化
// 如果塞不满,那么塞不满的部分就取数字1,由于 n x 1 = n,所以不影响最终结果
// 集合:dp[i][j]表示表示考虑数字1~i情况下,数字和≤j情况下的乘积
// 属性:乘积最大值
// 状态转移方程:dp[i][j] = max(dp[i -1][j], dp[i][j - i] *i,dp[i][j-2i]*i*i)
// 怎么代码简化上述状态转移方程参考acwing的完全背包问题
class Solution {
public:
int integerBreak(int n) {
if(n == 2){
return 1;
}
if(n == 3){
return 2;
}
vector<vector<int>> dp(n+10,vector<int>(n+10,1));
for(int i = 2;i<=n;i++){
for(int j = 2;j <= n;j++){
dp[i][j] = dp[i-1][j];
if(j >= i){
dp[i][j] = max(dp[i][j],dp[i][j-i] * i);
// 这一行很多细节的。
}
}
}
return dp[n][n];
}
};

本代码有很多细节:

  1. 为何要将全部初始状态赋予1?可能会考虑到初始化可以改成如下也行:
        vector<vector<int>> dp(n+10,vector<int>(n+10,0));
for(int j = 2;j<=n;j++){
dp[1][j] = 1;
}

其实是不行的,因为状态更新的时候有:

                if(j >= i){
dp[i][j] = max(dp[i][j],dp[i][j-i] * i);
// 这一行很多细节的。
}

第一次j==i的时候dp[i][j-i]=dp[i][0],因此dp[i][0]的初始值也应该赋1。

2. 为何要把2和3特殊处理提前返回?以2举例,2的正确答案应该是1,如果不提前返回,那么当进入到dp[i][j] = max(dp[i][j],dp[i][j-i] * i);会出现总和为2,那么可以选择一个2,答案就为2的情况。又因为在其他的选择方式中不存在结果比2大的情况,因此答案错误的输出2。总结来说:对于符合下列条件的数k需要提前返回:\(合法的结果 < k\)。满足此条件的数就是2和3。

为何只有2和3满足不赘述了,有需要再补充。

LeetCode刷题:343. 整数拆分的完全背包写法解析的更多相关文章

  1. leetcode刷题七<整数反转>

    给出一个 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 : 输入: 输出: 示例 : 输入: - 输出: - 示例 : 输入: 输出: 假设我们的环境只能存储得下 32 位的有符号整 ...

  2. Leetcode刷题——007.整数反转

    上代码: #include <cmath> class Solution { public: int reverse(int x) { ; long long tx=llabs(x); ) ...

  3. LeetCode 343. 整数拆分(Integer Break) 25

    343. 整数拆分 343. Integer Break 题目描述 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 每日一算法2019/5/2 ...

  4. Java实现 LeetCode 343 整数拆分(动态规划入门经典)

    343. 整数拆分 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 示例 1: 输入: 2 输出: 1 解释: 2 = 1 + 1, 1 × ...

  5. C#LeetCode刷题-动态规划

    动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串   22.4% 中等 10 正则表达式匹配   18.8% 困难 32 最长有效括号   23.3% 困难 44 通配符匹配   17.7% ...

  6. C#LeetCode刷题-数学

    数学篇 # 题名 刷题 通过率 难度 2 两数相加   29.0% 中等 7 反转整数 C#LeetCode刷题之#7-反转整数(Reverse Integer) 28.6% 简单 8 字符串转整数 ...

  7. leetcode刷题目录

    leetcode刷题目录 1. 两数之和 2. 两数相加 3. 无重复字符的最长子串 4. 寻找两个有序数组的中位数 5. 最长回文子串 6. Z 字形变换 7. 整数反转 8. 字符串转换整数 (a ...

  8. leetcode刷题-- 5. 动态规划

    动态规划思路 参考 状态转移方程: 明确「状态」-> 定义dp数组/函数的含义 -> 明确「选择」-> 明确 base case 试题 53最大子序和 题目描述 53 给定一个整数数 ...

  9. C#LeetCode刷题-字符串

    字符串篇 # 题名 刷题 通过率 难度 3 无重复字符的最长子串   24.6% 中等 5 最长回文子串   22.4% 中等 6 Z字形变换   35.8% 中等 8 字符串转整数 (atoi)   ...

  10. LeetCode刷题指南(字符串)

    作者:CYC2018 文章链接:https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Leetcode+%E9%A2%98%E8%A7% ...

随机推荐

  1. Vulhub Nginx漏洞复现

    目录 前言 文件名逻辑漏洞(CVE-2013-4547) 配置不当导致解析漏洞 配置错误导致漏洞 CRLF注入漏洞 目录穿越漏洞 前言 Nginx是一款广泛使用的Web服务器和反向代理服务器,尽管它以 ...

  2. java 中的Unsafe

    在阅读AtomicInteger的源码时,看到了这个类:sum.msic.Unsafe,之前从没见过.所以花了点时间google了一下. Unsafe的源码:http://www.docjar.com ...

  3. golang之热加载Fresh&air

    Fresh 是一个命令行工具,每次保存Go或模版文件时,该工具都会生成或重新启动Web应用程序.Fresh将监视文件事件,并且每次创建/修改/删除文件时,Fresh都会生成并重新启动应用程序.如果go ...

  4. pikachu文件上传_2024-11-26

    什么是文件上传漏洞 文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像.上传附件等等.当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型.后缀名.大小等等,然后 ...

  5. pve 下的群晖虚拟机硬盘空间扩容的记录

    pve下,105号群晖虚拟机,btrfs系统,sata硬盘. 虚拟机容量硬盘130G,扩展至140G,还需要命令行和网页存储管理器界面操作,以实现扩容的目的. df -h Filesystem Siz ...

  6. ehcarts 实战小计-1

    需求 展示未来未来36个月(等分为3个时间范围)的经济效益趋势,3个等分时间区域在趋势图上方常显,不同时间区域之间通过灰色虚线间隔开: 鼠标hover趋势图每个1/3区域,对应区域会有以下3个效果: ...

  7. 在CodeBolcks+wxWidgets下的C++编程教程——用向导创建一个wxWidgets项目(xTetris)

    0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程.我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识. 了解我编写教 ...

  8. 基于 .NET 的 Nuget 发版工具

    背景 由于 Natasha 及周边项目发版任务多,文件结构也不简单,之前一直使用基于 Github 管道脚本和 XUnit 来发版.这个方案对于发版环境与条件依赖性较强,且不够灵活,因此萌生出做一个本 ...

  9. day02 计算机组成

    day02 计算机组成 1.硬件 计算机硬件是指一些物理装置按照系统结构的要求构成一个有机整体为计算机软件运行提供物质基础 构成最基础的硬件有: CPU 内存 主板 IO设备 2.软件 计算机软件可以 ...

  10. 在openEuler RISC-V上无痛部署Solidity

    近几年区块链很火,随着各国政府对加密技术的监管政策不断变化和BTC的暴涨,越来越多人对这项去中心化的技术充满着期待.这次我用openEuler 24.09 RISC-V的远程机器尝试编译了Solidi ...