线性DP LIS浅谈

LIS问题

什么是LIS?

百度百科

最长上升子序列(Longest Increasing Subsequence,LIS),在计算机科学上是指一个序列中最长的单调递增的子序列。

怎么求LIS?

O(n^2)做法

具体做法是用两个for,状态转移方程为f[i]=max(f[i],f[j]+1)其中f数组为这个位置的LIS长度,然后用max找一下最长LIS即可

代码

for(int i=1;i<=n;i++)
  for(int j=1;j<i;j++)
  if(a[j]<a[i])
  f[i]=max(f[i],f[j]+1);
  for(int i=1;i<=n;i++)
  ans2=max(ans2,f[i]);

其中也可以取等号

O(nlogn)做法

具体做法是用数组去维护LIS,然后如果遇到比他小的二分数组

代码

if(u[ans2]<a[i])
    u[++ans2]=a[i];
    else
    u[lower_bound(u+1,u+ans2+1,a[i])-u]=a[i];

拓展定理(Dilworth定理)

什么是Dilworth定理?

百度百科

反链是一种偏序集,其任意两个元素不可比;而链则是一种任意两个元素可比的偏序集。Dilworth定理说明,存在一个反链A与一个将序列划分为链族P的划分,使得划分中链的数量等于集合A的基数。当存在这种情况时,对任何至多能包含来自P中每一个成员一个元#### 素的反链,A一定是此序列中的最大反链。同样地,对于任何最少包含A中的每一个元素的一个链的划分,P也一定是序列可以划分出的最小链族。偏序集的宽度被定义为A与P的共同大小。

另一种Dilworth定理的等价表述是:在有穷偏序集中,任何反链最大元素数目等于任何将集合到链的划分中链的最小数目。一个关于无限偏序集的理论指出,在此种情况下,一个偏序集具有有限的宽度w,当且仅当它可以划分为最少w条链。

对于LIS的用途

求LIS的个数就是求最长下降子序列的长度,注意其中的<之类的符号是取补集的,也就是说如果上面用的>那么反面就是<=

完整代码(洛谷模板题 P1020 导弹拦截)

O(nlogn)算法

#include <bits/stdc++.h>
using namespace std;
int a[100005],u[100005],l[100005];
bool cmp(int a,int b)
{
  return a>b;
}
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n=1;
  while(cin>>a[n]) n++;
  n--;
  int ans1=1,ans2=1;
  l[1]=u[1]=a[1];
  for(int i=2;i<=n;i++)
  {
    if(l[ans1]>=a[i])
    l[++ans1]=a[i];
    else
    l[upper_bound(l+1,l+ans1+1,a[i],cmp)-l]=a[i];
    if(u[ans2]<a[i])
    u[++ans2]=a[i];
    else
    u[lower_bound(u+1,u+ans2+1,a[i])-u]=a[i];
  }
  cout<<ans1<<" "<<ans2;
}

O(n^2)算法

#include <bits/stdc++.h>
using namespace std;
int a[100010];
int f[100010];
int main()
{
  int n=1;
  while(cin>>a[n])
  f[n++]=1;
  n--;
  int ans1,ans2;
  ans1=ans2=-1;
  for(int i=1;i<=n;i++)
  for(int j=1;j<i;j++)
  if(a[j]>=a[i])
  f[i]=max(f[i],f[j]+1);
  for(int i=1;i<=n;i++)
  ans1=max(ans1,f[i]);
  for(int i=1;i<=n;i++)
  f[i]=1;
  for(int i=1;i<=n;i++)
  for(int j=1;j<i;j++)
  if(a[j]<a[i])
  f[i]=max(f[i],f[j]+1);
  for(int i=1;i<=n;i++)
  ans2=max(ans2,f[i]);
  cout<<ans1<<" "<<ans2;
}

猜你喜欢

转载自www.cnblogs.com/baccano-acmer/p/9960078.html