问题描述:给出一个数列,找出其中最长的单调递减(或递增)子序列。

解题思路:

动态规划。假设0到i-1这段数列的最长递减序列的长度为s,且这些序列们的末尾值中的最大值是t。对于a[i]有一下情况:

(1) 如果a[i]比t小,那么将a[i]加入任何一个子序列都会使0到i的最长单调序列长度变成s+1,这样的话,在0到i的数列中,长度为s+1的递减子序列的末尾值最大值就是a[i];

(2) 如果a[i]和t相等,那么说明数列从0项到i项的最长单调子序列长度就是s;

(3) 如果a[i]比t大,那么a[i]就不一定能够成为长度为s的递减子序列的末项,这取决于长度为s-1的各个递减子序列的末尾值的最大值t'。

如果t'比a[i]要大,那么就可以形成长度为s的递减子序列,如果t'比a[i]小,那么问题就在往前递推,把a[i]和长度为s-2的各个递减子序列的末尾值的最大值比较,直到:(1) a[i]比长度为s'的递减子序列的末尾值的最大值要小,那么a[i]就是数列0到i部分长度为s'+1的递减子序列的末尾值中的最大值;(2) a[i]比任何长度的递减子序列的末尾值的最大值都要大,那么a[i]就是长度为1的递减子序列的最大值。

所以,引入数组c[i]表示长度为i的递减子序列的末尾值的最大值。显然c数组必然是单调递减的。b[i]数组用于子序列的输出,b[i]表示从a[0]到a[i]且终止于a[i]的最长递减序列的长度。

算法复杂度:

O(nlogn),对于数组c的查找使用二分查找,降低了整体的算法复杂度。

算法步骤:

1)读入n和a[i].

2)将数组c全部赋值为-1.

3)定义变量s,初始化为1,s表示目前为止最长单调序列的长度,同时也是数组C的有效容量。c[1] = a[0].

4)对于0到n-1的每个i:

查找c[1]到c[s],找到一个值k满足下列几种情况:

(1)c[k] <= a[i] 而 c[k-1] > a[i] (如果k>1)

(2)找不到(1)中k的话,k等于s+1,并且s自加一。

c[k] = a[i];

b[i] = k;

5)最后所得s即为所求值。

#include

//函数功能:打印最长子序列

//函数参数:a为源数组,b为存放序列长度的数组,k为最长子序列的末尾元素

//返回值 : 无

void print(int *a, int *b, int k)

{

int i;

for(i=k-1; i>=0; i--){

if(a[i]>a[k] && b[k]==b[i]+1){//当满足b[i] + 1 == b[k] && a[i] > a[k]时,a[i]就是前一个元素

print(a, b, i);//递归,一直到第一个元素

break;

}

}

printf("a[%d]=%d ", k, a[k]);//从第一个满足条件的元素开始打印

}

//函数功能 : 一个数组的最长递减子序列

//函数参数 : a指向源数组,len表示数组长度

//返回值 : 无

void find_mss(int *a, int len)

{

int i, j, maxi=0; //maxi用来记录最长递减序列的末尾元素

int *B = new int[len];

for(i=0; i

B[i]=1;

for(j=0;j

if(a[j]>a[i] && B[j]+1>B[i]){

B[i] = B[j]+1;

if(B[i]>B[maxi]){

maxi = i; //更新当前找到的最长递减序列

}

}

}

}

print(a, B, maxi);

}

int main()

{

int a[]={9,4,3,2,5,4,3,2};

int aa[]={9,8,6,5,3,5,4,2,1};

find_mss(a, 8);

printf("\n");

find_mss(aa, 9);

printf("\n");

return 0;

}

数组的最长递减子序列java_求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}...相关推荐

  1. 算法 求一个数组的最长递减子序列 C

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! //** ...

  2. 算法 - 求一个数组的最长递减子序列(C++)

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net /** 求一个数组的最长递减子序列 - C++ - ...

  3. 《团队开发一(求一个数组的连续的子数组之和的最大值)》

    <团队开发一(求一个数组的连续的子数组之和的最大值)> (1)设计思想:一般的,求一个数组的最大子数组之和即是按数组顺序依次让前几个数的和与下一个数进行比较,设一变量来装每次比较后的较大的 ...

  4. java 最大子数组_求一个数组中子数组的最大和算法(Java实现)

    前几天在微信订阅号"待字闺中"中看到的一篇文章<小技巧求一个数组中子数组的最大和>,提供下Java的实现,并且在对题目做下小修改,本来打算直接在微信里直接回复,但是发现 ...

  5. 求一个数组的非空子集

    //求一个数组的子集 #include <vector> #include<iostream> using namespace std; vector<vector< ...

  6. 13.在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。(左神算法基础班源码)

    package basic_class_01; /*** *小和问题在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和.求一个数组的小和.例子:[1,3,4,2,5]1左边比1小的数 ...

  7. python求数组平均值_用python求一个数组的和与平均值的实现方法

    用python求一个数组的和与平均值的实现方法 如下所示: # coding = GBK a =[1,2,3,4,5] sum=0 b = len(a) print("这个数组的长度为:&q ...

  8. 求一个数组的最大k个数(java)

    问题描述:求一个数组的最大k个数,如,{1,5,8,9,11,2,3}的最大三个数应该是,8,9,11 问题分析: 1.解法一:最直观的做法是将数组从大到小排序,然后选出其中最大的K个数,但是这样的解 ...

  9. 算法12--topK求一个数组中第k大的数

    求一个数组中第k大的值 解法一: 建立一个k个元素的最大堆,首先将数组中前k个元素放入堆中,此时堆顶元素为第k大的元素,后面继续遍历数组,比较堆顶元素与数组中元素值,当数组中元素小于堆顶元素时,将堆顶 ...

最新文章

  1. 如何写新的C++ OP
  2. colorAccent,colorPrimary,colorPrimaryDark 作用的地方
  3. MCSE2003学习之六
  4. 谷歌开源 MobileNetV3:新思路 AutoML 改进计算机视觉模型移动端
  5. 浅谈runtime运行时机制
  6. 昨天尝试了Layout,也谈Silverlight的布局
  7. linux在没有x远程桌面,xmanager远程桌面控制linux
  8. Redux学习(一)——Redux的使用过程
  9. apexsql使用方法_使用ApexSQL审核执行SQL Server审核
  10. 滚动效果--marquee的使用
  11. 【Java程序设计】类与对象的基本概念(下)
  12. Strtus2标签s:url
  13. 12.软件架构设计:大型网站技术架构与业务架构融合之道 --- CAP理论
  14. 解决Boost库链接出错问题
  15. 关于总时差和自由时差的作用及理由
  16. linux获取软电话信息,完整的SIP软电话工程实施过程
  17. nero6.0使用教程
  18. QEMU中TCG翻译流程
  19. 如何安装最新版本的office(preview预览版)、更新
  20. linux poweroff无法关机,linux关机重启六种方法(sysrq shutdown halt init ipmi poweroff)

热门文章

  1. 找出Java进程中大量消耗CPU
  2. 用python简单查找大文件
  3. HelpDesk工作流多级,多任务流程(包含源代码和InfoPath模板)
  4. RGB转换cv::Mat
  5. WSL1升级到WSL2
  6. VAD实现(一) 读取语音数据
  7. Android系统信息获取 之二:版本信息获取
  8. Clojure 学习入门(8)- 连接mongodb
  9. jstring转换到C语言所用的char
  10. Android APK系列5-------修改APK中的内容