O(nlogn)实现LCS与LIS

时间:2024-04-14 19:33:30

序:
LIS与LCS分别是求一个序列的最长不下降序列序列与两个序列的最长公共子序列
朴素法都可以以O(n^2)实现。
LCS借助LIS实现O(nlogn)的复杂度,而LIS则是通过二分搜索将复杂度从n^2中的朴素查找导致的n降至logn使之整体达到O(nlogn)的复杂度。

具体解析:
http://www.cnblogs.com/waytofall/archive/2012/09/10/2678576.html


LIS代码实现:

/*
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:01