自己在做有关俄罗斯套娃的题目时,发现自己写出的一个方法可以解决求最长上升子序列(LIS)和最长下降子序列(LDS)的问题。

俄罗斯套娃:这个问题在前一篇中讲的有,在此处就不多讲了~链接

 求最长上升子序列:

给定排好序的一堆数列中,求其的LIS长度。它的LIS长度就是它非上升子序列的个数。

WHY?

其实自己模拟一下就可以发现:计算出第一组非上升子序列,它的最后一个数一定是这组数列的最小的一个数;第二组非上升子序列的最后一个数就一定会是剩下的数中最小的一个..........哪么,上升子序列的长度是多少,就一定可以排出多少组非上升子序列~但每一组非上升子序列的最后一个数并不一定就是所求上升子序列的里的数,但每一组一定有一个数是所求最长上升子序列里的数.........

PS:(把上面这段话写清楚一些~)

因为给出的数字(a[])是已经排好序的,因此这组数字的最长上升子序列的第一个数(用b[0]表示),b[0]应该在这组数(a[])的第一组非上升子序列里面。

WHY1?

//     这是因为第一组最长非上升子序列是从这组数的第一个数字开始的而且是能搜索到这组数(a[])最小的数字的!!!故最长上升子序列的第一个数b[0],只能在第一组非上升子序列里~

哪么~b[0]确定的话,b[1]是绝对不会在b[0]这组里面,它存在于第二组非上升子序列里~

WHY2?

//     因为排好的是第一组非上升子序列,若b[0]确定是这组的某个数,哪么该数后面的数绝对<=b[0],故b[1]只会在第二组非上升子序列里,至于这个为什么~请参照WHY1(为什么b[0]在第一组非上升子序列里)

同理~剩下b[]就在接下来的非上升子序列里了~~~~~

............................. = =感觉写的还是........不是很清楚啊.........算了~就这样了,懒得再写了~.....= =

那么肿么输出最长上升子序列?

从最后开始记起~另开一个数组b[]记录LIS值。设给定的数组为a[],它的LIS的长度为number,并把数组已经按非上升子序列分好组,并已经作好标记(列如:是第一组非上升子序列,就标记为1;是第2组就标记为2;以此类推.......)。

从数列的最后开始扫描,当a[i]=number时,就记录b[number]=a[i],并且number--;......一直扫到a[0]结束~b[]记录的就是其中一组的最长上升子序列~

例如:9,10,6,7,2,1,8,4,3,5

第一组非上升子序列是:9 6 2 1--------------记为1

第二组非上升子序列是:10 7 4 3-------------记为2

第三组非上升子序列是:8 5-------------------记为3

那么从后面扫到的第一个符合要求的是5,接着是3,再者是1

然后输出的是:1 3 5

1 3 5就是这组数列其中最小的一组最长上升子序列~

在此感谢荆红浅醉小童鞋的帮助~~

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; class P
{
public:
int x,id;
}a[]; int main()
{
int n,i,j,number,minn,b[];
while(~scanf("%d",&n))
{
memset(a,,sizeof(a));
for(i=;i<n;i++)
scanf("%d",&a[i].x);
number=;
printf("LIS:\n");
for(i=;i<n;i++)
if(a[i].id==)
{
number++; //有一组新的非上升子序列,个数就加1
a[i].id=number;
minn=a[i].x;
for(j=i+;j<n;j++)
{
if(a[j].id== && a[j].x<=minn)
{
a[j].id=number; //是哪一组的非上升子序列就记录下来它的组值~
minn=a[j].x; //更新每一组非上升子序列的最小值
}
}
}
for(i=n-,j=number;i>=;i--) //从数列的后面开始扫描~
{
if(a[i].id==j) //当遇到id为j,就是所要输出的值,要记入数组b[]中,并找下一个要求值,此时j--
{
b[j]=a[i].x;
j--;
}
}
for(i=;i<=number;i++) //输出的b[]就是所求的一个最长上升子序列(应该是最小的一个~)
printf("%d ",b[i]);
printf("\nLIS number:");
printf("%d\n",number);
}
return ;
}

那么~求最长下降子序列方法与上面相反~

LIS,LDS的另类算法(原)的更多相关文章

  1. BZOJ 1609 [Usaco2008 Feb]Eating Together麻烦的聚餐:LIS & LDS (nlogn)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1609 题意: 给你一个只由数字"1,2,3"组成的序列a[i],共n个 ...

  2. POJ 1836 Alignment --LIS&LDS

    题意:n个士兵站成一排,求去掉最少的人数,使剩下的这排士兵的身高形成“峰形”分布,即求前面部分的LIS加上后面部分的LDS的最大值. 做法:分别求出LIS和LDS,枚举中点,求LIS+LDS的最大值. ...

  3. 多校联合练习赛1 Problem1005 Deque LIS+LDS 再加一系列优化

    Deque Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  4. k均值聚类算法原理和(TensorFlow)实现

    顾名思义,k均值聚类是一种对数据进行聚类的技术,即将数据分割成指定数量的几个类,揭示数据的内在性质及规律. 我们知道,在机器学习中,有三种不同的学习模式:监督学习.无监督学习和强化学习: 监督学习,也 ...

  5. LIS的O(nlogn)算法

    出自蓝书<算法竞赛入门经典训练指南> 求最长上升子序列是很常见的可以用动态规划解决的问题…… 很容易根据最优子结构之类的东西得出 $\text{dp}[i]$为以第i个数结尾的最长上升子序 ...

  6. K-means聚类算法原理和C++实现

    给定训练集$\{x^{(1)},...,x^{(m)}\}$,想把这些样本分成不同的子集,即聚类,$x^{(i)}\in\mathbb{R^{n}}$,但是这是个无标签数据集,也就是说我们再聚类的时候 ...

  7. 机器学习之感知器算法原理和Python实现

    (1)感知器模型 感知器模型包含多个输入节点:X0-Xn,权重矩阵W0-Wn(其中X0和W0代表的偏置因子,一般X0=1,图中X0处应该是Xn)一个输出节点O,激活函数是sign函数. (2)感知器学 ...

  8. URL短网址生成算法原理和php实现案例

    短网址(Short URL),顾名思义就是在形式上比较短的网址. 短链接的好处:1.内容需要:2.用户友好:3.便于管理为什么要这样做的,原因我想有这样几点:微博限制字数为140字一条,那么如果我们需 ...

  9. LIS(nlogn)算法描述//线性DP经典类型

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

随机推荐

  1. Jquery div边框大全

    网址 http://jquery.malsup.com/corner/ jQuery Corner是一款jQuery的插件,最初由Dave Methvin开发,但后在Malsup同志的协助下,进行了一 ...

  2. cenots 下的 lamp(备份与恢复)

    用 putty连接数据库: mysql -uroot -p密码 create database yourdb DEFAULT CHARACTER SET utf8 COLLATE utf8_chine ...

  3. php 简单的验证码

    注意事项: 验证的隐藏域的位置一定要在调用JS前.. 如: <input type="text" name="yzm" value="" ...

  4. google+ 登录API 使用 javascript sdk 快速入门 (图解)

    准备工作: 打开Google API 控制台 : https://code.google.com/apis/console 点击 My Project (我的项目) 按照图示流程,您将完成一个goog ...

  5. 一个Highcharts的例子

    关键字:Highcharts <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Typ ...

  6. visual studio 生成后事件 Post-Build Event

    提出问题:我们的解决方案中有两个可执行程序,主程序运行后,会通过process.start()打开多个子程序.调用process.start的时候,需要指定子程序的可执行路径,把子程序的可执行程序放到 ...

  7. STM32内存映射

    一.概述 STM32内存映射是STM32的架构的重要组成部分,不可或缺. 二.STM32内存映射图 1.内存映射图--摘自<CM3权威指南> 2.内存映射图--摘自<STM32F10 ...

  8. E8.Net 工作流二次开发架构平台

    一.          产品简介 E8.Net工作流开发架构是基于微软.Net技术架构的工作流中间件产品,是国内商业流程管理(BPM)领域在.Net平台上的领先产品,是快速搭建流程管理解决方案的二次开 ...

  9. 【转】成为Java顶尖程序员 ,看这11本书就够了

    成为Java顶尖程序员 ,看这11本书就够了 转自:http://developer.51cto.com/art/201512/503095.htm 以下是我推荐给Java开发者们的一些值得一看的好书 ...

  10. Axure草记

    页面控件和DataSet绑定,DataSet和输入控件绑定(通过临时变量) 双击Repeater进入之后,你会发现下面已经默认添加了3行,这代表着,每增加一行将会重复3遍: Repeater可以只是部 ...