LIS模板

来源:互联网 发布:js 执行上下文 编辑:程序博客网 时间:2024/06/05 07:10
/*1.O(n?)算法定义dp[i]:以ai为结尾的最长上升子序列的长度以ai结尾的上升子序列是:①只包含ai的子序列②在满足j<i并且aj<ai的以aj为结尾的上升子列末尾,追加上ai后得到的子序列综合以上两种情况,便可以得到递推关系式:dp[i] = max{1, dp[j]+1| j<i且aj<ai}*///O(n^2)  1.本身1;2如果j<i;a[j]<a[i],则dp[i]=dp[j]+1; #include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 30010;int dp[maxn], a[maxn];//dp[i]存的是以i结尾的最长子序列 int main(){int n;while(scanf("%d",&n)!=EOF){for(int i=0;i<n;++i)              scanf("%d",&a[i]);          int ans=0;          for(int i=0;i<n;++i)          {              dp[i]=1; //最短为本身一             for(int j=0;j<i;++j)              {                  if(a[j]<a[i])                      dp[i] = max(dp[i], dp[j]+1);              }               ans=max(dp[i],ans);          }          printf("%d\n",ans);  }return 0;} 

/*定义dp[i]:长度为i+1的上升子序列中末尾元素的最小值(不存在就是INF)最开始全部dp[i]的值都初始化为INF。然后由前到后逐个考虑数列的元素,对于每个aj,如果i=0或者dp[i-1]<aj的话,就用dp[i]=min(dp[i],aj)进行更新。最终找出使得dp[i]<INF的最大的i+1就是结果了。*///O(nlogn)原理是什么我也不知道啊 #include <cstdio>  #include <algorithm>  #define INF 0x3f3f3f  using namespace std;  int dp[30010],a[30010];  int main()  {      int n,i,j;      while(scanf("%d",&n)!=EOF)      {          for(i=0;i<n;++i)          {              scanf("%d",&a[i]);              dp[i]=INF;          }          for(i=0;i<n;++i)              *lower_bound(dp,dp+n,a[i])=a[i];//把a[i]放进第一个大于等于a[i]的位置          printf("%d\n",lower_bound(dp,dp+n,INF)-dp);// 输出第一个INF的位置     }      return 0;  }    

 
原创粉丝点击