zoukankan      html  css  js  c++  java
  • LIS,LDS的另类算法(原)

          自己在做有关俄罗斯套娃的题目时,发现自己写出的一个方法可以解决求最长上升子序列(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就是这组数列其中最小的一组最长上升子序列~ 

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

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 class P
     7 {
     8 public:
     9     int x,id;
    10 }a[1000];
    11 
    12 int main()
    13 {
    14     int n,i,j,number,minn,b[1000];
    15     while(~scanf("%d",&n))
    16     {
    17         memset(a,0,sizeof(a));
    18         for(i=0;i<n;i++)
    19             scanf("%d",&a[i].x);
    20         number=0;
    21         printf("LIS:
    ");
    22         for(i=0;i<n;i++)
    23             if(a[i].id==0)
    24             {
    25                 number++;                   //有一组新的非上升子序列,个数就加1
    26                 a[i].id=number;
    27                 minn=a[i].x;                
    28                 for(j=i+1;j<n;j++)
    29                 {
    30                     if(a[j].id==0 && a[j].x<=minn)
    31                     {
    32                         a[j].id=number;     //是哪一组的非上升子序列就记录下来它的组值~
    33                         minn=a[j].x;       //更新每一组非上升子序列的最小值
    34                     }
    35                 }
    36             }
    37         for(i=n-1,j=number;i>=0;i--)      //从数列的后面开始扫描~
    38         {
    39             if(a[i].id==j)                //当遇到id为j,就是所要输出的值,要记入数组b[]中,并找下一个要求值,此时j--
    40             {
    41                 b[j]=a[i].x;
    42                 j--;
    43             }
    44         }
    45         for(i=1;i<=number;i++)           //输出的b[]就是所求的一个最长上升子序列(应该是最小的一个~)
    46             printf("%d ",b[i]);
    47         printf("
    LIS number:");
    48         printf("%d
    ",number);
    49     }
    50     return 0;
    51 }

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

  • 相关阅读:
    Golang Failpoint 的设计与实现
    没涉及到最值求解;观点:矩阵乘法无法表达出结果。 现实生活中事件、现象的数学表达
    多元微分学 枚举破解15位路由器密码 存储空间限制 拆分减长,求最值 数据去重
    ARP Poisoning Attack and Mitigation Techniques ARP欺骗 中间人攻击 Man-In-The-Middle (MITM) attack 嗅探 防范 Can one MAC address have two different IP addresses within the network?
    The C10K problem
    HTTP Streaming Architecture HLS 直播点播 HTTP流架构
    现代IM系统中消息推送和存储架构的实现
    现代IM系统中的消息系统架构
    长连接锁服务优化实践 C10K问题 nodejs的内部构造 limits.conf文件修改 sysctl.conf文件修改
    doubleclick cookie、动态脚本、用户画像、用户行为分析和海量数据存取 推荐词 京东 电商 信息上传 黑洞 https://blackhole.m.jd.com/getinfo
  • 原文地址:https://www.cnblogs.com/teilawll/p/3238065.html
Copyright © 2011-2022 走看看