动态规划3.3 最长递增子序列

 问题:

  在一个数组中寻找最长递增子序列。

动态规划方法:

  当一个数要加入进来的时候有两种方法:

  1、前面的数都比当前的数大(或者相等),因此,以这个数为止的最长递增子序列长度就是1。数组中的第一个数一般预先填好,或者设置哨兵。

  2、前面的数有比当前的数小的,那么以这个数为止的最长递增子序列长度就是states[i] = max(states[i], states[j] + 1);所以对于每一个states[i]要

     遍历它前面的states数组,并且对于每一个num[i] 要比较它前面的num数组来作为控制条件。

代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 int main()
 5 {
 6     #define LEN 7
 7     int num[ LEN ] = {2, 9, 3, 6, 5, 1, 7};
 8     
 9     int states[LEN] = {0};
10     
11     states[0] = 1;
12     
13     int max_subsequence = 1;
14     for(int i = 1; i < LEN; i++)
15     {
16         for(int j = 0; j < i; j++)
17         {
18             if(num[i] > num[j])
19             {
20                 states[i] = std::max(states[i], states[j] + 1);
21             }
22         }
23         max_subsequence = std::max(max_subsequence, states[i]);
24     }
25     
26         
27     std::cout << "max_subsequence : " << max_subsequence << std::endl;
28     
29     return 0;
30 }

运行结果:

 

 把最长子序列之一打印出来,需要借助一个pre数组,代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stack>
 4 int main()
 5 {
 6     #define LEN 7
 7     int num[ LEN ] = {2, 9, 3, 6, 5, 1, 7};
 8     int pre[ LEN ] = {0};  // 用于记录前一个数的索引
 9     pre[0] = -1;
10     
11     int states[LEN] = {0};
12     states[0] = 1;
13     
14     for(int i = 1; i < LEN; i++)   // 这个for循环里面先不记录递增序列的全局最大值,最后统一搜索
15     {
16         pre[i] = -1;
17         for(int j = 0; j < i; j++)
18         {
19             if(num[i] > num[j])
20             {
21                 if(states[j] + 1 > states[i])
22                 {
23                     states[i] = states[j] + 1;
24                     pre[i] = j;
25                 }
26             }
27         }
28     }
29     
30     int max_subsequence = 1;
31     int max_index = 0;
32     for(int i = 0; i < LEN; i++)    // 统一搜索最大值
33     {
34         if(states[i] > max_subsequence)
35         {
36             max_subsequence = states[i];
37             max_index = i;
38         }
39     }
40         
41     std::stack<int> s;
42     while(max_index != -1)
43     {
44         s.push(num[max_index]);
45         max_index = pre[max_index];
46     }
47     
48     std::cout << "max_subsequence : " << max_subsequence << std::endl;
49     
50     std::cout << "subsequence : ";
51     while(!s.empty())
52     {
53         std::cout << s.top() << " ";
54         s.pop();
55     }
56     std::cout << std::endl;
57     
58     return 0;
59 }

运行结果:

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/13494477.html