最长上升子序列问题是各类信息学竞赛中的常见题型,也常常用来做介绍动态规划算法的引例,笔者接下来将会对poj上出现过的这类题目做一个总结,并介绍解决lis问题的两个常用算法(n^2)和(nlogn).
问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7...an,求它的一个子序列(设为s1,s2,..
sn),使得这个子序列满足这样的性质,s1 例如有一个序列:1 7 3 5 9 4 8,它的最长上升子序列就是 1 3 4 8 长度为4.
算法1(n^2):我们依次遍历整个序列,每一次求出从第一个数到当前这个数的最长上升子序列,直至遍历到最后一个数字为止,然后再取dp数组里最大的那个即为整个序列的最长上升子序列。我们用dp[i]来存放序列1-i的最长上升子序列的长度,那么dp[i]=max(dp[j])+1,(j∈[1, i-1]);显然dp[1]=1,我们从i=2开始遍历后面的元素即可。
下面是模板:
//最长上升子序列(n^2)模板。
//入口参数:1.数组名称 2.数组长度(注意从1号位置开始)
template
int lis(t a,int n)
return ans;
算法2(nlogn):维护一个一维数组c,并且这个数组是动态扩展的,初始大小为1,c[i]表示最长上升子序列长度是i的所有子串中末尾最小的那个数,根据这个数字,我们可以比较知道,只要当前考察的这个数比c[i]大,那么当前这个数一定能通过c[i]构成一个长度为i+1的上升子序列。当然我们希望在c数组中找一个尽量靠后的数字,这样我们得到的上升子串的长度最长,查找的时候使用二分搜索,这样时间复杂度便下降了。
模板如下://最长上升子序列nlogn模板。
//入口参数:数组名+数组长度,类型不限,结构体类型可以通过重载运算符实现。
//数组下标从1号开始。
begin_template_by_abilitytao_acm
template
int bsearch(t c,int n,t a)
template
int lis(t a,int n)
return size;
二级C语言教程课后习题详解
新视野教育二级c语言教程课后习题详解。以修订版教材为准 第一章 c语言的基础知识。第二节熟悉visual c 1.c语言源程序名的后缀是 b a exeb cc objd cp c语言源程序的拓展名为。c 2.下列叙述中错误的是 d a 计算机不能直接执行用c语言编写的源程序。b c程序经c编译后,...
c c语言入门基础教程教程
十 引用 引用和指针类似,都是直接对变量地址操作,区别是引用对象不能改变,引用要直观好理解一些,下面我们来看一个练习 1 启动 geany 1 点菜单 应用程序 编程 geany 启动 geany 新建一个 c 源程序 2 点菜单 文件 另存为 命令,以 refer 为文件名,保存文件到自己的文件夹...
C语言教案笔记
教案。授课主要内容。组织教学。1 清点学生到校情况。2 课程介绍 主要内容 学习方法 要求及参考资料 教学目标。1.了解计算机语言的发展及特点。2.了解c语言的相关特点及学习c语言的必要性。3.掌握c语言程序的基本结构。4.了解程序 算法的概念。新课导入。1 曾经学习过哪些计算机知识及相关内容。2 ...