主要谈两个
LCS
见dp->最长公共子序列
http://blog.csdn.net/wu_tongtong/article/details/76998351
LIS
主要介绍nlogn算法
g[1]=num[1]; //长度为1的最小
//f[1]=1; 写完会发现f可有可无
int t=1; //当前最长上升子序列的长度
for (i=2;i<=n;i++)
{
int l=1,r=t,mid;
while (l<=r)
{
mid=(l+r)>>1;
if (g[mid]<num[i]) //找到小于a[i]的最大的一个
l=mid+1; //mid+1 不知不觉就+1
else r=mid-1;
}
g[l]=num[i]; //l就是长度
//f[i]=l;
if (l>t) t=l;
}
return t; //最长上升子序列长度
那要是最长不降怎么办呢
int le=1;
f[1]=a[1];
for (i=2;i<=n;i++)
{
if (a[i]>=f[le]) f[++le]=a[i]; //直接接上
else f[upper_bound(f+1,f+1+le,a[i])-f]=a[i];
//upper_bound >的第一个数
}
return le;
大佬的码风,果然优美,这就激发我yy一种LIS的stl写法
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int g[1000010];
int main()
{
scanf("%d",&n);
int len=1;
for (int i=1;i<=n;i++)
{
int u;
scanf("%d",&u);
if (i==1)
{
g[1]=u; //g单调不减
continue;
}
if (u>g[len]) g[++len]=u;
else g[lower_bound(g+1,g+1+len,u)-g]=u;
//lower_bound >=的第一个
}
printf("%d",len);
}