Algorithm 二维矩阵中最长的递增子序列。

Algorithm 二维矩阵中最长的递增子序列。,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我正在解决一个编程难题,即在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][

我正在解决一个编程难题,即在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);
scanf(“%d”和&N);

对于(i=1;i来说,在O(n3)时间内解决这个问题并不是那么困难。但是,我没有阅读源代码,所以我不知道下面是否是它所做的,但是这里有一个如何实现它的想法

诀窍就在更新过程中。我猜你最初做的是以下几点

你说你在考虑橙色矩形中的一个元素。前面的步骤必须来源于蓝色矩形(你已经解决了)。这会得到正确的答案,但是很容易看出它会产生一个(n4)结果,因为你可以同时得到橙色和蓝色的矩形(n2),并且你需要考虑它们之间的所有对。(很容易将其形式化。)

相反,从只解第一行和第一列开始。事实上,在每次迭代中,取下一个未解的行和列,并从先前解的部分解出它们

这里有一个技巧(我将留给你)。如果你在单元格中存储了足够的信息(或者在辅助数据结构中,这无关紧要),那么对于你正在考虑的橙色列中的每个元素,你只需要查看它左边的列(橙色行也一样-你只需要查看它上面的行中的元素)


所以有O(n)外迭代(每一行都考虑一行和一列)。每个这样的行/列都有O(n)元素,每个左/上行/列都有O(n)元素两个。乘法给出了你的目标复杂度。

非常感谢!!。我不知道为什么我没有考虑这个问题。我会尝试相应地编写代码。@Shimano不客气,祝你好运!只要确定你需要为每个单元格存储哪些辅助信息(提示:列中橙色单元格的路径实际上源于它左边的列,或者不是)。酷:). 谢谢你的精美插图。我想我现在明白了。