1

私はSPOJで問題を試みていました。この問題では、指定された配列 Aの最長増加サブシーケンスの長さを単純に見つける必要があります。

私は動的プログラミングO(n ^ 2)アルゴリズムを使用してこの問題を解決し、解決策が受け入れられました..受け入れられたコードは次のとおりです。

void LIS(int *A,int A_Length)
{
    int Seq[MAX];
    for(int i=0;i<A_Length;++i)
    {
        int maxima=0;
        for(int j=0;j<i;++j)
        {
            if(A[i]>A[j])
            {
                maxima=max(Seq[j],maxima);
            }
        }
        Seq[i]=maxima+1;
        //cout<<Seq[i]<<endl;
    }
    cout<<*max_element(Seq,Seq+A_Length)<<endl;
}

しかし、私が2番目の方法( LINK )を使用して解決しようとしたとき、それは::

A simple way of finding the longest increasing subsequence is
 to use the Longest Common Subsequence (Dynamic Programming) algorithm.
[1]Make a sorted copy of the sequence A, denoted as B. O(nlog(n)) time.
[2]Use Longest Common Subsequence on with A and B. O(n2) time.

、私は間違った答えを得ました。

これは私のC++コードです

//Global Variable
int A[100],B[100];
int DP[100][100];

//This function Finds the Longest common subsequce of Array A[1,2,3...,N] and B[1,2,3...,N]
void LIS(int N)
{

    sort((B+1),(B+1)+N);//STL SORT sort from index 1 to N of Array B.
    int i,j;

    //Base Cases
    for(i=0;i<=N;++i)
        DP[i][0]=0;

    for(j=0;j<=N;++j)
        DP[0][j]=0;

    for(i=1;i<=N;++i)
    {
        for(j=1;j<=N;++j)
        {
            if(A[i]==B[j])
                DP[i][j]=DP[i-1][j-1]+1;
            else
                DP[i][j]=max(DP[i-1][j],DP[i][j-1]);
        }
    }
    printf("%d\n",DP[N][N]);
}
int main()
{
    int N,i;
    scanf("%d",&N);
    for(i=1;i<=N;++i)
    {
        scanf("%d",&A[i]);
        B[i]=A[i];
    }
    LIS(N);

    return 0;
}

間違った答えが返ってきた理由がわかりません。バグを見つけるのを手伝ってください。または、サイトに記載されている LCS アルゴリズムによる LISが正しくありませんか??

4

1 に答える 1

2

2 番目の方法は正しいですが、この問題に直接適用することはできません。これは、この SPOJ 問題ではシーケンス内の数値が一意であることが保証されておらず、厳密に増加するサブシーケンスを見つけることが目標であるのに対し、Your Second Method の出力は非減少サブシーケンスであるためです。簡単なテスト ケースでデモを行う[1,2,2,3]と、違いを見つけるのに役立ちます。

この解決策も簡単です。並べ替え後に重複した要素を削除するだけです。

于 2012-07-26T13:51:40.633 に答える