最长上升子序列模板

来源:互联网 发布:java wait和notify 编辑:程序博客网 时间:2024/06/08 14:55



1、动态规划法

#include <stdio.h>  #define  MAX 1000  int seq[MAX+10];  int seqlen[MAX+10];  int main()  {      int i,j,k,N,max,maxlen=1;      for(i=1;i<=9;i++)          seqlen[i]=1;               //seqlen数组存以第i个数为终点的最长上升序列      scanf("%d",&N);      for(i=1;i<=N;i++)          scanf("%d",&seq[i]);       //seq数组保存序列数组      for (i=2;i<=N;i++)      {          max=0;          for (j=1;j<=i-1;j++)          {              if(seq[j]<seq[i]&&seqlen[j]>max)  //在前i-1个序列中,寻找以终点小于seq[i]的最长的子序列,即最优子状态                  max=seqlen[j];          }          seqlen[i]=max+1;          if(seqlen[i]>maxlen)           //seqlen中保存的是第i个数为终点的最长上升序列,找出这个数组中最大的值即为最优序列长度              maxlen=seqlen[i];      }      printf("%d/n",maxlen);      return 0;  }  




2、Nlog(N)复杂度解法

#include <iostream>  #include<cstdio>  #include<string.h>  using namespace std;  #define Maxn 50010    typedef long long ll;  ll arr[Maxn],ans[Maxn],len;        int main()  {      ll p,i,j,k;      //scanf("%d",&T);      //while(T--)      //{          scanf("%lld",&p);          for(i=1;i<=p;i++)          {              scanf("%lld",&arr[i]);            }          ans[1]=arr[1];          len=1;          for(i=2;i<=p;i++)          {              if(arr[i]>ans[len])                  ans[++len]=arr[i];              else{                  ll pos =lower_bound(ans+1,ans+len,arr[i])-ans;                  ans[pos]=arr[i];              }            }          printf("%lld\n",len);     // }      return 0;  }  



3、LCS方法


先将序列从小到大排序,然后用最长公共子序列(LCS)去匹配

下面给出LCS算法的实现:(复杂度为N^2)

#include<stdio.h>  #include<string.h>  #include<algorithm>  using namespace std;  const int maxn = 1E3 + 10;  char a[maxn],b[maxn],ans[maxn];  int dp[maxn][maxn];  int main(){          scanf("%s%s",a + 1,b + 1);          int n = strlen(a+1),m = strlen(b+1);          memset(dp,0,sizeof(dp));          for(int i = 1 ; i <= n ; ++i){                  for(int j = 1 ; j <= m ; ++j){                          if(a[i] == b[j]){                                  dp[i][j] = dp[i-1][j-1] + 1;                          }else dp[i][j] = max(dp[i][j-1],dp[i-1][j]);                  }          }          int cur = 0;          for(int i = n,j = m;dp[i][j];--i,--j){//返回到第一次更新值的地方                  while(dp[i][j] == dp[i - 1][j])     --i;                  while(dp[i][j] == dp[i][j - 1])     --j;                  ans[cur++] = a[i];          }          reverse(ans,ans+cur);          ans[cur] = '\0';          printf("%s\n",ans);          return 0;  }  


原创粉丝点击