📌  相关文章
📜  可以放入其他较大信封中的最大信封数(1)

📅  最后修改于: 2023-12-03 15:22:56.474000             🧑  作者: Mango

可以放入其他较大信封中的最大信封数

在纸张业界,通常使用信封尺寸标准命名法。其中,信封的大小通常用信封高度(纵向)和信封宽度(横向)两个参数来描述。例如,一个C4信封的尺寸为229mm x 324mm。

现在假设我们有n个信封,每个信封都有一个不同的尺寸。我们想将其中的一些信封放入另外一些更大的信封中,以此实现封装效果,假设两个信封时,如果一个信封的尺寸比另一个信封大,则只能将小信封放入大信封中。相反,若两个信封相等,则它们之间不能嵌套。

现在问题来了:给你一些信封的尺寸,怎样放才能使得最多的信封被放入其中一些较大的信封中?

这个问题可以转化为最长递增子序列问题。具体来说,假设我们将信封按照一个维度排序(例如,按照信封高度或宽度排序)。我们可以使用动态规划的方法求得最长递增子序列(LIS),这个值就是可以被嵌套的信封最大数目。

动态规划求解

我们定义一个数组dp来记录信封嵌套的数量。假设已经将信封按照某个维度排好序了,则对于dp[i],表示以第i个信封为结尾的最长递增子序列长度,它的值可以通过如下转移方程计算:

dp[i] = max(dp[j] + 1),其中0 <= j < i,envelopes[j] < envelopes[i]

其中envelopes[j] < envelopes[i]表示第i个信封可以嵌套在第j个信封中。这样,dp[i]就表示以信封i为结尾的最长递增子序列长度。

最后,我们对数组dp求最大值,就是最多可以放入其他较大信封中的最大信封数。

代码实现

下面是一个Python实现的例子:

def maxEnvelopes(envelopes: List[List[int]]) -> int:
    if not envelopes:
        return 0

    # 按照宽度排序,如果宽度一样,则按照高度逆序排序
    envelopes.sort(key=lambda x: (x[0], -x[1]))

    n = len(envelopes)
    dp = [1] * n
    for i in range(n):
        for j in range(i):
            if envelopes[j][1] < envelopes[i][1]:
                dp[i] = max(dp[i], dp[j] + 1)

    return max(dp)
性能分析

时间复杂度:O(n ^ 2),其中n是信封的数量。内层循环中的条件只涉及到i和j,因此循环次数为n * n,即O(n ^ 2)。

空间复杂度:O(n),其中n是信封的数量。dp数组的长度为n,因此需要O(n)的空间复杂度。