最大递增子序列问题
2015-07-17 22:11
302 查看
[题目]
设序列L=<a1,a2,a3,⋯,an>L = < a_1, a_2, a_3, \cdots, a_n >是长度为n的序列,LL的一个递增序列描述为:<ai1,ai2,⋯,aik>, 其中下标序列 <i1,i2,⋯,ik>< i_1, i_2, \cdots, i_k>是递增的, 子序列<ai1,ai2,⋯,aik>< a_{i1}, a_{i2}, \cdots, a_{ik}> 也是递增的,求此递增序列的长度为 k。[分析]
常用的动态规划思想算法复杂度为O(n2)O(n^2),改进后的采用二分查找的算法复杂度为O(nlogn)O(nlogn)。具体分析过程参见下面的博客,讲解的很详细,易懂:最大递增子序列问题我实现的核心代码如下:
#include <iostream> using namespace std; int main(){ int a[10] = {1,3,4,2,7,5,9,6,8,10}; //待测试数组 int len=0,t[10]; //t[递增子序列长度]=结尾处的最小值 t[1]=a[0]; //初始化 len=1; //记录当前的最大递增子序列长度 int l,p,r; //二分法的下界、中点、上界 for(int i=1; i<10; i++){ l=1; r=len; while(l<=r){ //二分查找 p=(l+r)/2; if(t[p]<a[i]) l=p+1; else r=p-1; } t[l]=a[i]; if(l>len) len++; } cout<<len<<endl; return 0; }
在杭电oj(1025)-Constructing Roads In JGShining’s Kingdom应用的代码如下:
#include <iostream> #include <stdio.h> #include <algorithm> using namespace std; #define MAX 500010 typedef struct roads{ int pool; int rich; }; roads rd[MAX]; int t[MAX]; bool cmp(roads a, roads b){ if(a.pool < b.pool) return true; return false; } int main(){ int N,num=1; freopen("input","r",stdin); while(scanf("%d",&N)!=EOF){ for(int i=0; i<N; i++) scanf("%d%d",&rd[i].pool,&rd[i].rich); //注意这里要用scanf,使用cin会超时 sort(rd,rd+N,cmp); t[1]=rd[0].rich; int len=1; int l,m,r; for(int i=1; i<N; i++){ l=1; r=len; while(l<=r){ m=(l+r)/2; if(t[m] < rd[i].rich) l=m+1; else r=m-1; } t[l]=rd[i].rich; if(l>len) len++; } printf("Case %d:\n",num++); if(len==1) printf("My king, at most %d road can be built.\n\n",len); else printf("My king, at most %d roads can be built.\n\n",len); } return 0; }
相关文章推荐
- 2-SAT
- 【动态规划】【树状数组】[USACO2011 FEB]奶牛抗议
- QinQ封装及终结详解
- 黑马程序员----反射
- 黑马程序员----Java阶段性总结
- polymer-developer guide-registration and lifecycle
- MyBatis知多少(10)应用程序数据库
- c++ 之自己写库函数 (静态库)
- 实战 SSH 端口转发
- 机器人网站查询
- 黑马程序员----正则表达式,OMG
- 准备开源一套异形UI控件
- 第三周编程作业 数字特征值
- Java学习笔记-------布局管理器
- 极客学院网站视频php自学使用心得
- Maximal Rectangle
- 黑马程序员----拜拜DOS,helloGUI
- 黑马程序员----网络编程
- ajaxSubmit上传文件出现下载提示框问题
- VXLAN技术学习笔记