최대 상승 하위 시퀀스(LIS)

최대 상승 하위 서열 문제는 두 가지 해법이 있다.
1. DP의 사상을 활용하여 n번째 위치의 최대 상승자 서열을 판단할 때 n앞의 수를 모두 한 번 훑어보고 앞의 노드를 비교한다. 앞의 노드의 상승자 서열+1이 현재 노드의 상승자 서열보다 크면 갱신되고 시간 복잡도는 n*n이다.
코드는 다음과 같습니다.
#include <bits/stdc++.h>  // DP
using namespace std;
#define N 40010
int dp[N];
int data[N];

int main()
{
    int T, n, ans;
    cin>>T;
    while(T--)
    {
        cin>>n;
        ans = 0;
        for(int i=0; i<n; i++)
            dp[i] = 1;
        for(int i=0; i<n; i++)
            scanf("%d", &data[i]);
        for(int i=1; i<n; i++)
        {
            for(int j=i-1; j>=0; j--)
            {
                if(data[j]<data[i] && dp[j]+1 > dp[i])
                    dp[i] = dp[j] + 1;
            }
            ans = max(ans, dp[i]);
        }
        cout<<ans<<endl;
    }
    return 0;
}
2.2분의 사상을 사용했는데 복잡도는 n*log(n)이다.
#include <bits/stdc++.h>
using namespace std;
#define N 40010
int Binary(int *a, int l, int r, int value)
{
    while(l<=r)
    {
        int mid = (l+r) / 2;
        if(a[mid] > value)
            r = mid-1;
        else
            l = mid+1;
    }
    return l;
}
int data[N];
int ans[N];
int main()
{
    int T, n;
    cin>>T;
    while(T--)
    {
        cin>>n;
        int cnt = 0;
        for(int i=0; i<n; i++)
            scanf("%d", &data[i]);
        ans[0] = data[0];
        for(int i=1; i<n; i++)
        {
            if(data[i]>ans[cnt])
            {
                ans[++cnt] = data[i];
            }
            else
            {
                int in = Binary(ans, 0, cnt, data[i]);
                ans[in] = data[i];
            }
        }
        for(int i=0; i<=cnt; i++)
            cout<<ans[i]<<" ";
        cout<<endl;
        cout<<cnt+1<<endl;
    }
    return 0;
}

좋은 웹페이지 즐겨찾기