zoukankan      html  css  js  c++  java
  • 求最长递减子序列(转载)

    Q:例如:有一个序列,例如 9 8 2 1 7 5 3 4 3 2 1.
         求出最长的递减子序列。如本例的结果就是:9 8 7 5 4 3 2 1。

    分析:

            可采用动态规划的思想进行解答,时间复杂度为O(n^2).

           设原数组为a[1....n]。另设一数组d[1....n],其中d[i]表示从第i个元素开始(一定包含第i个元素),到整个数组末尾的子序列 a[i...n]中的最长递减子序列的长度。
           则本问题就是要在求出d[1]的同时,恢复出最优解。

       下面给出递推式:

    d[i]的值分两种情况:
    1、当i=n时,d[i]=1。即最后一个元素的序列的最大递减子序列中只有它自己。


    2、当i<n时,d[i]=max{d[k]| i<k<=n 且a[i]>a[k]} +1。解释意思为,包含第i个元素的序列a[i...n]的最大子序列依赖于i后面所有的序列中比a[i]小(满足递减
    特性),且最大的d[k](满足最 优特性)值再加1(加上a[i]元素)。在给d[i]赋值的时候只需记录p[i]=k,既可以作为parent属性恢复出解。

    具体实现的话,开两个数组d[n],p[n],外层循环从后往前选取i,内层循环从i往后寻找最优的k,双循环遍历即可求出所有的d[i]。然后 再进行一次O(n)操作,找出最大的d[max]。恢复解的话,可以从p[max]开始,依次恢复出各个解。

     1 #include <iostream.h>
     2 
     3 void longest_decrease_sub(int *a, int size)
     4 {
     5     
     6     int *d=new int[size]; //分配内存空间    
     7     int *p=new int[size];  //分配内存空间
     8     
     9     d[size-1]=1;
    10     
    11     for(int i=size-1;i>=0;i--)
    12     {
    13         
    14         int max=0;
    15         
    16         int index=0;
    17         
    18         for(int j=i;j<size;j++)
    19         {
    20             
    21             if(a[i]>a[j] && max <d[j])
    22             {
    23                 
    24                 max=d[j];
    25                 
    26                 index=j;
    27                 
    28             }
    29             
    30         }
    31         
    32         if(max==0)
    33         {
    34             
    35             d[i]=1;
    36             
    37             p[i]=-1;
    38             
    39         }
    40         else
    41         {
    42             
    43             d[i]=max+1;
    44             
    45             p[i]=index;
    46             
    47         }
    48         
    49     }
    50     
    51     //寻找最大子序列的起始下标
    52     
    53     int max=0;
    54     
    55     int max_index=0;
    56     
    57     for( i=0;i<size;i++)
    58     {
    59         
    60         if(d[i]>max)
    61         {
    62             
    63             max=d[i];
    64             
    65             max_index=i;
    66             
    67         }
    68         
    69     }
    70     
    71     //从最大子序列的下标开始 输出子序列    
    72     cout<<"\n最长递减子序列的长度为:"<<d[max_index]<<",最长子序列为:"<<ends;
    73     
    74     for( i=max_index;i!=-1;i=p[i])
    75     {
    76         
    77         cout<<a[i]<<" "<<ends;
    78         
    79     }
    80     
    81     delete [] d;
    82     
    83     delete [] p;
    84     
    85 }
    86 
    87 void main()
    88 {
    89     int data[10]={1,2,5,4,3,2,7,8,9,0};
    90     longest_decrease_sub(data,10);
    91 }

     

     

  • 相关阅读:
    Win10 UWP Tile Generator
    Win10 BackgroundTask
    UWP Tiles
    UWP Ad
    Win10 build package error collections
    Win10 八步打通 Nuget 发布打包
    Win10 UI入门 pivot multiable DataTemplate
    Win10 UI入门 导航滑动条 求UWP工作
    UWP Control Toolkit Collections 求UWP工作
    Win10 UI入门 SliderRectangle
  • 原文地址:https://www.cnblogs.com/Trony/p/2618566.html
Copyright © 2011-2022 走看看