最长上升子序列
来源:互联网 发布:国家人工智能战略 编辑:程序博客网 时间:2024/06/04 23:29
示例题目:POJ2533
参考书籍:《挑战程序设计竞赛》
第一种方法:O(n^2)
dp[i]:以a[i]结尾的最长上升子序列的长度
- 只包含a[i]的序列
- 由a[j]追加a[i]得到(满足j< i并且a[j]< a[i])
状态转移方程:
dp[i]=max{dp[i],dp[j]+1}
#include<iostream>#include<cstring>#include<cmath>#include<algorithm>using namespace std;int a[1005];int dp[1005];int main(){ ios::sync_with_stdio(false); int n; while(cin>>n) { for(int i=1;i<=n;i++) { cin>>a[i]; } memset(dp,0,sizeof(dp)); int res=0; for(int i=1;i<=n;i++) { dp[i]=1; for(int j=1;j<i;j++) { if(a[i]>a[j]) dp[i]=max(dp[i],dp[j]+1); } res=max(dp[i],res); } cout<<res<<endl; } return 0;}
第二种方法:O(nlogn)
dp[i]:长度为i+1的上升子序列中末尾元素的最小值(不存在就是INF)
状态转移方程:
对数列从左往右扫一遍,对于当前扫到的元素a[j]
如果i=0或者dp[i-1]< a[j],就用dp[i]=min(dp[i],a[j])更新,
考虑到dp数列中除INF外是单调递增的,dp[i]的指针可由
lower_bound(dp,dp+n,a[j])得出。
#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;int a[1005];int dp[1005];/// dp[i]表示长度为i+1的上升子序列中末尾元素的最小值/// 不存在就是INFint main(){ //int t[5]={1,2,4,4,5}; //cout<<lower_bound(t,t+5,3)-t<<endl; ios::sync_with_stdio(false); int n; while(cin>>n) { for(int i=0;i<n;i++) { cin>>a[i]; } fill(dp,dp+n,INF); for(int i=0;i<n;i++) { *(lower_bound(dp,dp+n,a[i]))=a[i]; } cout<<lower_bound(dp,dp+n,INF)-dp<<endl; } return 0;}
按照白书上的理解
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;int a[1005];int dp[1005];//dp[i]:以a[i]结尾的LIS的长度int g[1005];//g[k]=a[j] (dp[j]=k&&j最小)///g[1]<=g[2]<=g[3]<=...<=g[n] (if not exist g[i]=INF)///dp[i]=max(0,dp[j])+1 (j<i&&a[j]<a[i])int main(){ int n; while(cin>>n) { for(int i=0;i<n;i++) cin>>a[i]; fill(g,g+n+1,INF); for(int i=0;i<n;i++) { //g[k']<a[i]<=g[k] (k=k'+1) int k=lower_bound(g+1,g+n+1,a[i])-g; //g[k']=a[j']<a[i] dp[j']=k'=k-1 //g[k]=a[j]>=a[i] dp[i]=k; //dp[i]=max(0,dp[j'])+1=k (j'<i&&a[j']<a[i]) g[k]=a[i]; } cout<<lower_bound(g+1,g+n+1,INF)-(g+1)<<endl; } return 0;}
1 0
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- Python的语法总结
- [HNOI2017]影魔sf
- qtservice创建服务程序
- 消除webView黑边
- Http请求中Content-Type详解
- 最长上升子序列
- [转]Linux下STM32开发环境的搭建
- sudo和rpm命令
- 【科普】VR视频与全景视频有什么不同?
- java/jsp获取当前时间是本年的第几周
- opencv中读取图像的绝对路径问题
- 监听键盘高度实现评论功能
- 如何解决高版本Google Chrome(谷歌浏览器)扩展程序强制停用问题?或者经常提示停用扩展程序
- STLmap、multimap、unordered_map、unordered_multimap差异