O(nlogn)實現LCS與LIS

序:
LIS與LCS分別是求一個序列的最長不降低序列序列與兩個序列的最長公共子序列
樸素法均可以以O(n^2)實現。
LCS藉助LIS實現O(nlogn)的複雜度,而LIS則是經過二分搜索將複雜度從n^2中的樸素查找致使的n降至logn使之總體達到O(nlogn)的複雜度。 html

具體解析:
http://www.cnblogs.com/waytofall/archive/2012/09/10/2678576.htmlc++


LIS代碼實現:markdown

/* About: LIS O(nlogn) Auther: kongse_qi Date:2017/04/26 */
#include <bits/stdc++.h>
#define maxn 10005
using namespace std;

int n, x[maxn];

void Init()
{
    scanf("%d", &n);
    for(unsigned i = 0; i != n; ++i)
    {
        scanf("%d", &x[i]);
    }
    return ;
}

int lower_find(int cur, int t, int x[])
{
    int l = 0, r = t, mid;
    while(l < r-1)
    {
        mid = (l+r)/2;
        if(x[mid] > cur)    r = mid;
        else l = mid+1;
    }
    return (x[l] >= cur ? l : r);
}

int Lis()
{
    int dp[maxn], top_pos = -1, pos;
    dp[++top_pos] = x[0];
    for(unsigned i = 1; i != n; ++i)
    {
        if(x[i] > dp[top_pos])
        {
            dp[++top_pos] = x[i];
            continue;   
        }
        pos = lower_find(x[i], top_pos, dp);//手寫或直接調用STL的lower_bound函數尋找下界
        //pos = lower_bound(dp, dp+top_pos+1, x[i])-dp;
        if(dp[pos] > x[i])  dp[pos] = x[i];
    }
    return top_pos+1;
} 

int main()
{
    freopen("test.in", "r", stdin);

    Init();
    printf("%d\n", Lis());
    return 0;
}

LCS代碼實現函數

/* About: LCS O(nlogn) Auther: kongse_qi Date:2017/04/26 */
#include <bits/stdc++.h>
#define maxn 1005
using namespace std;

int n, m, a[maxn], b[maxn];
vector<int> x[maxn];
vector<int> dp;
typedef vector<int>::iterator iterator_t;

void Init()
{
    scanf("%d%d", &n, &m);
    for(unsigned i = 0; i != n; ++i)
    {
        scanf("%d", &a[i]);
    }
    for(unsigned i = 0; i != m; ++i)
    {
        scanf("%d", &b[i]);
    }
    return ;
}

void Pre()
{
    for(unsigned i = m-1; i != -1; --i)
    {
        x[b[i]].push_back(i);
    }
    for(unsigned i = 0; i != n; ++i)
    {
        if(!x[a[i]].empty())
        {
            for(iterator_t j = x[a[i]].begin(); j != x[a[i]].end(); ++j)
            {       
                dp.push_back(*j);
            }
        }
        else dp.push_back(0);
    }
    return ;
}

int Lis()
{
    int qi[maxn], top_pos = -1, pos;
    qi[++top_pos] = dp[0];
    for(iterator_t i = dp.begin()+1; i != dp.end(); ++i)
    {
        if(*i > qi[top_pos])
        {
            qi[++top_pos] = *i;
            continue;   
        }
        pos = lower_bound(qi, qi+top_pos+1, *i)-qi;
        if(qi[pos] > *i)    qi[pos] = *i;
    }
    return top_pos+1;
}

int main()
{
    //freopen("test.in", "r", stdin);

    Init();
    Pre();
    printf("%d\n", Lis()); 
    return 0;
}

自此結束。
箜瑟_qi 2017.04.26 9:01ui

相關文章
相關標籤/搜索