最长递增子序列长度(动态规划)

来源:互联网 发布:gps导航软件下载 编辑:程序博客网 时间:2024/06/08 14:53

状态方程:

MaxLen (1) = 1

MaxLen (k) = Max { MaxLen (i)+1:1<i < k 且 ai < ak }(取所有MaxLen里面最大那个拿出来当最长子序列的长度)


当然丢出一个状态方程可能会比较懵逼,讲道理过一段时间我再回来看可能也会懵逼,所以我得举一个小例子来讲一下


给定的数组为{5,6,7,1,2,8},则MaxLen(0)=1, MaxLen(1)=2, MaxLen(2)=3, MaxLen(3)=1, MaxLen(4)=2, MaxLen(5)=4。所以该数组最长递增子序列长度为4,序列为{5,6,7,8}。


其实MaxLen记录的是这一个数的时候他的递增子序列的长度是多少,然后最后取最长的就ok了



代码:

#include <stdio.h>  #include <iostream>  #define  MAX 1000  int seq[MAX+10];  int seqlen[MAX+10];  int main()  {      int i,j,k,N,max,maxlen=1;      scanf("%d",&N);      for(i=1;i<=N;i++)          seqlen[i]=1;               //seqlen数组存以第i个数为终点的最长上升序列 ,首先现在把他们全部赋1的意思就是还没计数的时候就算自己本身就是1     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]的最长的子序列,即最优子状态     判断条件,前一个的值小于后一个,然后i这个点的值设为j点的值加一                 max=seqlen[j];          }          seqlen[i]=max+1;          if(seqlen[i]>maxlen)           //seqlen中保存的是第i个数为终点的最长上升序列,找出这个数组中最大的值即为最优序列长度    这里就是找最大的那个点             maxlen=seqlen[i];      }      printf("%d/n",maxlen);      return 0;  }