【DP】最长不下降子序列问题(二分)
2015-08-19 20:34
483 查看
Description
给你一个长度为n的整数序列,按从左往右的顺序选择尽量多的数字并且满足这些数字不下降。
给你一个长度为n的整数序列,按从左往右的顺序选择尽量多的数字并且满足这些数字不下降。
Thinking
朴素dp算法:F[i]表示到第i位为止的最长不下降子序列长度 F[i]=max(F[j])+1,其中(j<i且a[j]<=a[i]) 时间复杂度:O(n2) 考虑维护一个队列g,用g[i]表示长度为i的最长不下降子序列结尾的最小值。根据g[i]的单调性,可以用二分查找的方法快速找到以当前数a[i]结尾的最长不下降子序列.Code
#include<cstdio> #include<cstring> #define FA(i,s,t) for(int i=s;i<=t;i++) #define FD(i,s,t) for(int i=s;i>=t;i--) using namespace std; int n; int num[10000]; int g[10000],f[10000]; void Insert(int x,int s,int t) //不使用递归的方法提高效率 { int left,right,mid; left=s; right=t; while(left<=right) { mid=(left+right)/2; if(g[mid]==x) { while(g[mid]==x) ++mid; g[mid]=x; return; } if(g[mid]>x) right=mid-1; if(g[mid]<x) { if(g[mid+1]>x) { g[mid+1]=x; return; } left=mid+1; } } } int main() { scanf("%d",&n); FA(i,1,n) { scanf("%d",&num[i]); } memset(g,0,sizeof(g)); int t=1; FA(i,1,n) { if(num[i]>=g[t-1]) { g[t]=num[i]; t++; } else { Insert(num[i],0,t); } } int ans=t-1; printf("%d\n",ans); return 0; }
相关文章推荐
- HDU 2089 不要62(数位dp)
- ReflectedBitmap(倒影效果)
- Java关键字final、static使用总结
- Hdu oj 2066 一个人的旅行
- div滚动字幕
- Activity的2种启动方式
- OC数组的四大遍历方式和分析。
- 一个ajax的Post要求
- PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(2)
- 简单且线程安全的两个单例模式java程序
- arraylist的使用
- sql 随机函数newid()
- Android 循环滑动viewpager
- HDU 5339 Untitled 状态压缩 BC round49 A
- UICollectionView在初始化的时候移动到某个距离
- iOS面试题五
- 时间改变一切
- VS编译设置
- C程序存储空间布局(一)——各数据段的内存位置
- 面试题收集