lis最长递增子序列

lis的实现有三种,一种是简单的O(n^2)的dp,第二种是转化为lcs,用原序列排序后得到一个有序的序列,并求两序列的最长公共子序列。这种可以比较方便地打印出答案,复杂度也是O(n^2)。最后是维护一个为某个长度时该长度序列的最后一个数可取的最小值,用了二分查找将复杂度降到O(nlogn)。

 1 //LIS
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <list>
 5 #include <vector>
 6 
 7 using namespace std;
 8 
 9 int dp[105];
10 
11 void lis(int *p, int n) {
12     memset(dp, 0, sizeof(dp));
13 
14     for (int i = 1;i < n;i++) {
15         dp[i] = dp[i - 1];
16         for (int j = 0;j < i;j++)
17             if (p[i] > p[j])dp[i] = max(dp[i], dp[j] + 1);
18     }
19     cout << dp[n - 1];
20 }
21 
22 int d[105][105];
23 void lcs(int*p, int* q, int m, int n) {//m,n为两个数组的长度
24 
25     memset(d, 0, sizeof(d));
26 
27     for (int i = 1;i<m + 1;i++)
28         for (int j = 1;j < n + 1;j++) {
29             if (p[i - 1] == q[j - 1])d[i][j] = d[i - 1][j - 1] + 1;
30             else d[i][j] = max(d[i - 1][j], d[i][j - 1]);
31         }
32 }
33 
34 void print_ans(int* p, int* q, int m, int n) {//lcs的打印
35     if (d[m][n] <= 0)return;
36 
37     if (d[m][n] == d[m - 1][n - 1] + 1) {
38         print_ans(p, q, m - 1, n - 1);
39         cout << p[m - 1];
40     }
41     else if (d[m][n] = d[m - 1][n])
42         print_ans(p, q, m - 1, n);
43     else
44         print_ans(p, q, m, n - 1);
45     //cout << endl;
46 }
47 
48 int binarysearch(int* a, int len, int val) {
49     int left = 0, right = len;//左闭右开
50     while (left < right) {
51         int mid = (left + right) / 2;
52         if (a[mid] > val)
53             right = mid;
54         else if (a[mid] < val)
55             left = mid + 1;
56         else
57             return mid;
58     }
59     return left;
60 }
61 
62 int lis1(int *p, int n) {
63     int *a = new int[n];
64     int length = 1;
65     a[0] = p[0];
66 
67     for (int i = 1;i < n;i++) {
68         if (p[i] > a[length - 1])
69             a[length++] = p[i];
70         else
71             a[binarysearch(a, length, p[i])] = p[i];
72     }
73 
74     delete a;
75     return length;
76 }

 

posted on 2018-04-01 13:02  只是个回忆录  阅读(146)  评论(0编辑  收藏  举报

导航