【力扣】刷题备忘录-动归-343. 整数拆分

343. 整数拆分

c 复制代码
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++){ // 这里j的最大值去到i-2就可以,这时i - j = 2 正好能用初始化的值
                dp[i] = max(dp[i], max(j * dp[i - j], j * (i - j))); // 1. 执行拆分 有两种可能的来源 
                                                                    //2. 还要和dp[i]去比 然后更新
                // std::cout << "i的当前值是:" << i << std::endl;
                // std::cout << "dp i的当前值是:" << dp[i] << std::endl;
            }
        }
       return dp[n];
    }
};
  1. 这题难点在于想到 有两种可能的来源 一个是当前拆分后直接相乘的结果 另一个是拆出来的数字对应到dp table上的解相乘的结果
  2. 优化点在于想到 拆分相乘的时候j不需要去查dpj。
  • 至于原因,代码随想录给的是因为拆分j的情况,在遍历j = 1 to i -2 的过程中都考虑到了。
  • 我认为还有一个解释是,把这个求解过程展开,比如,dp5 = 2 × 3, dp6 = 3 × 3等,就会发现其实最大值都是由2 3组成的。所以把代码又优化成了下面这样:
c 复制代码
class Solution {
public:
    int integerBreak(int n) {
        if (n <= 3) return n -1; // 这里要记得处理,不然当n<=3的时候,循环里面dp[4]取不到值 会报错
        vector<int> dp(n+1);
        dp[2] = 1;
        dp[3] = 2;
        for (int i = 4; i <= n; i++) {
            for (int j = 1; j <= 3; j++){  // 这里只用考虑j <= 3的情况
                dp[i] = max(dp[i], max(j * dp[i - j], j * (i - j))); 
            }
        }
       return dp[n];
    }
};

其实分析到这里也可以写贪心了,但二刷的事情就留给二刷去做吧,这个优化方案其实已经不是动归本身了,而是基于数学做的改进了。

相关推荐
FlightYe40 分钟前
视界原理之3D视频(四):裸眼、眼镜和头显
android·linux·c++·3d·ffmpeg·音视频
by209992 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
Rover Ramble2 小时前
C++ 用互斥锁实现读写锁
开发语言·c++
你怎么知道我是队长3 小时前
C++零基础入门第2周:数据类型、运算符与表达式完全指南(附20段可运行代码+避坑清单)
c++
say_fall3 小时前
【Linux系统编程】Ext 文件系统:磁盘与存储、文件与目录、现代计算机究竟如何寻找文件
linux·运维·服务器·数据库·c++
雪落漂泊3 小时前
C++算法 滑动窗口篇(下)
开发语言·c++
文丑颜不良啊3 小时前
LeetCode1661~1680题目解析
java·leetcode
你怎么知道我是队长6 小时前
C++零基础第3周:if/else、switch、for/while/do-while 控制流完全指南(附20段可运行代码+避坑清单)
java·开发语言·c++
青少儿编程课堂7 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:倍增法求最近公共祖先LCA解析
c++·python·算法·bfs·信息学竞赛
雷✘7 小时前
C++ 类与对象的初始化机制、成员访问边界与拷贝优化
java·网络·c++