LeetCode刷题:343. 整数拆分的完全背包写法解析
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?可能会考虑到初始化可以改成如下也行:
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. 整数拆分的完全背包写法解析的更多相关文章
- leetcode刷题七<整数反转>
给出一个 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 : 输入: 输出: 示例 : 输入: - 输出: - 示例 : 输入: 输出: 假设我们的环境只能存储得下 32 位的有符号整 ...
- Leetcode刷题——007.整数反转
上代码: #include <cmath> class Solution { public: int reverse(int x) { ; long long tx=llabs(x); ) ...
- LeetCode 343. 整数拆分(Integer Break) 25
343. 整数拆分 343. Integer Break 题目描述 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 每日一算法2019/5/2 ...
- Java实现 LeetCode 343 整数拆分(动态规划入门经典)
343. 整数拆分 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 示例 1: 输入: 2 输出: 1 解释: 2 = 1 + 1, 1 × ...
- C#LeetCode刷题-动态规划
动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串 22.4% 中等 10 正则表达式匹配 18.8% 困难 32 最长有效括号 23.3% 困难 44 通配符匹配 17.7% ...
- C#LeetCode刷题-数学
数学篇 # 题名 刷题 通过率 难度 2 两数相加 29.0% 中等 7 反转整数 C#LeetCode刷题之#7-反转整数(Reverse Integer) 28.6% 简单 8 字符串转整数 ...
- leetcode刷题目录
leetcode刷题目录 1. 两数之和 2. 两数相加 3. 无重复字符的最长子串 4. 寻找两个有序数组的中位数 5. 最长回文子串 6. Z 字形变换 7. 整数反转 8. 字符串转换整数 (a ...
- leetcode刷题-- 5. 动态规划
动态规划思路 参考 状态转移方程: 明确「状态」-> 定义dp数组/函数的含义 -> 明确「选择」-> 明确 base case 试题 53最大子序和 题目描述 53 给定一个整数数 ...
- C#LeetCode刷题-字符串
字符串篇 # 题名 刷题 通过率 难度 3 无重复字符的最长子串 24.6% 中等 5 最长回文子串 22.4% 中等 6 Z字形变换 35.8% 中等 8 字符串转整数 (atoi) ...
- LeetCode刷题指南(字符串)
作者:CYC2018 文章链接:https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Leetcode+%E9%A2%98%E8%A7% ...
随机推荐
- 在哪里可以找到官方的mysql容器图像?
如果您在容器上部署MySQL,那么首要任务之一就是找到正确的镜像. 有一定程度的混乱,尤其是当我们试图帮助部署有问题的人时. 例如,当人们说我使用的是官方的docker镜像- 这到底意味着什么?Doc ...
- 我和JVM初次约会
前言:该篇是参考结合<高手深度解析:JVM是什么>,自己剔除添加了一些内容整理的而来,这里感谢<高手深度解析:JVM是什么>的文章的指点讲解. JVM的生命周期 "J ...
- python之模拟数据Faker
Faker,它解决的问题是python模拟(随机)数据!不知道大家在工作中没有用到过假数据,特别前后端开发的人员,应该经常用到,前端人员页面展示,效果展示.后端人员数据库数据模拟.今天给大家介绍的这个 ...
- CudaSPONGE之Python接口
技术背景 在上一篇博客中我们介绍了CudaSPONGE的基本安装和使用方法.为了性能考虑,CudaSPONGE是基于纯CUDA C开发的,但是现在很多轮子都是Python开发的.为兼容更多的框架和平台 ...
- js 实现可缓存方法
1.概述 有些场景下,如果一些函数需要大量的运算,但是他们的传入的参数是一样的,这个时候,我们可以将这些运算缓存下来,之后的运算就可以不用重复计算了. 2.实现方法 <script> // ...
- Echarts 颜色管理
1.Echarts的颜色设计 Echarts的颜色的设置分为两种:色盘和具体颜色 色盘适合做全局设置,因为他里面有多个颜色,通俗的说色盘就是颜色预设值列表,色盘统一使用color属性进行配置. 而具体 ...
- js 计算过去和未来的时间距离现在多少天
计算传入的任意一时间.计算出这个时间距离现在还有多少天!或者计算过去的时间距离现在已经过去了多少天! 返回值有两种! 1.负值 代表过去了多少天 2.正值 代表距离设定的时间还有多少天 说明:距离设定 ...
- C语言离散化
C语言离散化 最近看到STL就不想用, 于是写个C语言离散化, 居然能过主席树板子, 就写个博客介绍一下. qsort和bsearch都在<stdlib.h>或<cstdlib> ...
- C++顺序结构(2)学习任务
在坚果云中注册免费个人云盘 一.视频下载存放在规划好的文件夹中,并观看学习 1.变量存储.注释 2.四则运算.输入 3.认识设置DEV-C++ 4.第一个C++程序 5.头文件 6.命名空间 7.co ...
- 对比 ASP.NET Core 中的 HttpContext.Features 与 HttpContext.Items
对比 ASP.NET Core 中的 HttpContext.Features 与 HttpContext.Items https://newbedev.com/httpcontext-feature ...