分割整数的实例与代码

来源:9-3 发现重叠子问题 Integer Break

慕标6347362

2018-12-31

你好,老师!我反复听这个例子,都没能理解这个递推关系。可以在这里套入视频中以4的作为例子再解释一下?
在老师代码 memo[i]= max3(memo[i], j * (i - j), j * memo[i - j]); 中的j * (i - j)j * memo[i - j]分别在图中实例代表哪些数的乘积?尤其为什么j * memo[i - j]可以作为备选项?

图片描述

class Solution {
private:
    int max3(int a, int b, int c) {
        return max(a, max(b, c));
    }
public:
    int integerBreak(int n) {
        assert(n >= 2);

        // memo[i]表示将数字i分割(至少分割两部分)后得到的最大乘积
        vector<int> memo(n + 1, -1);

        // 自底向上:所以最小分成1, 1的最大乘积是1,所以1
        memo[1] = 1;
        for (int i = 2; i <= n; i++)
            // 求解memo[i]
            for (int j = 1; j <= i - 1; j++)
                // j + (i-j)
                memo[i]= max3(memo[i], j * (i - j), j * memo[i - j]);
        return memo[n];
    }
};

int main() {
    return 0;
}

谢谢!!!

写回答

1回答

liuyubobobo

2018-12-31

理解算法的关键,就是理解算法中的每一个变量,每一个函数的语义。


在这个程序中,memo[x]的语义是:将x分割几个整数的和,他们乘积的最大值。

在这个语义的基础上,对于任意一个数字i,我们将其进行分割:

或者将其拆成两部分,一部分是j的话,另一部分就是i - j,对应j * (i - j);

或者将其拆分成三个或者三个以上的部分,此时,我们先考虑分割出的一个数字为j,之后,还要对剩下的i-j进行分割。剩下的i - j进行分割后乘积的最大值是memo[i - j](回顾上面memo的语义!),在加上我们已经分割出的j,所以分割i得到的乘积的最大值,就是 j * memo[i - j]。


看看能否理解?继续加油!新年快乐!:)

1
3
慕标6347362
非常感谢!
2019-01-01
共3条回复

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7410 学习 · 1150 问题

查看课程