【问题标题】:Longest increasing subsequence in a 2D matrix.二维矩阵中最长的递增子序列。
【发布时间】:2016-05-04 02:46:35
【问题描述】:

我正在解决一个编程挑战,以找到 2D NxN 矩阵中最长递增子序列的长度。序列的每个元素中的行和列都必须增加(不需要是连续的)。我用动态编程方法解决了它,但它是 O(N^4) 且效率低下。但是,在 O(N^3) 中有很多解决方案。一种这样的解决方案是:

   scanf("%d", &N);
    for(i = 1; i <= N; i++) {
        for(j = 1; j <= N; j++) {
            scanf("%d", &L[i][j]);
        }
    }
    Answer = 0; 

    memset(maxLength,0,sizeof(maxLength));
    for (i=1;i<=N;i++) 
    {
        maxLength[1][i] = 1;
        maxLength[i][1] = 1;
    }

    //
    for (i=2;i<=N;i++)
    {

        memset(minValue,0,sizeof(minValue));
        curLen = 1;
        minValue[1] = L[i-1][1]; 

        for (j=2;j<=N;j++)  
        {
            for (p=1;p<i;p++)
            {
                tmpLen = maxLength[p][j-1];
                if (minValue[tmpLen] == 0)
                {
                    minValue[tmpLen] = L[p][j-1]; 
                    curLen = tmpLen;
                }
                else if (minValue[tmpLen]>L[p][j-1])
                {
                    minValue[tmpLen] = L[p][j-1];
                }
            }


            max = 1;
            for (p=curLen;p>0;p--)
            {
                if (L[i][j]>=minValue[p])
                {
                    max = p+1;
                    break;
                }
            }

            maxLength[i][j] = max;
            Answer = Answer>max?Answer:max;
        }
    }

    // Print the answer to standard output(screen).
    printf("%d\n", Answer);

有人可以解释它是如何工作的或任何其他 O(N^3) 方法吗?我根本听不懂:(。

【问题讨论】:

    标签: algorithm dynamic-programming


    【解决方案1】:

    O(n3) 时间内解决这个问题并不难。但是,我没有阅读源代码,所以我不知道以下是否是它所做的,但这里有一个关于如何完成的想法。

    诀窍在于更新过程。我猜你最初做的是以下内容。

    假设您正在考虑橙色矩形中的一个元素。上一步必须源自蓝色矩形(您已经解决了)。这会产生一个正确的答案,但很容易看出它会产生 Θ(n4) 结果,因为您可以同时制作橙色和蓝色矩形 Θ(n2),你需要考虑它们之间的所有对。 (这很容易形式化。)

    相反,首先解决第一行和第一列。实际上,在每次迭代中,取下一个未解决的行和列,并从之前解决的部分中解决它们。

    这是诀窍(我将留给你)。如果您在单元格中存储了足够的信息(或在辅助数据结构中,没关系),那么对于您正在考虑的橙色列中的每个元素,您只需要查看它左侧的列(同上对于橙色行 - 您只需查看其上方行中的元素)。

    因此存在 O(n) 次外部迭代(在每个迭代中,您都考虑一行和一列)。每个这样的行/列都有 O(n) 个元素,每个左/上行/列有两个 O(n) 个元素。乘法给出了您的目标复杂度。

    【讨论】:

    • 非常感谢!!这使它非常清楚:)。我不知道为什么我没有考虑过。我将尝试对其进行相应的编码。
    • @Shimano 不客气,祝你好运!只需确保您弄清楚每个单元格需要存储的辅助信息是什么(提示:列中橙色单元格的路径实际上来自它左侧的列,或者它不是)。
    • 酷:)。也感谢精美的插图。我想我现在明白了。
    猜你喜欢
    • 1970-01-01
    • 2011-07-19
    • 2021-09-02
    • 2018-03-26
    • 2013-07-03
    • 2017-07-10
    相关资源
    最近更新 更多