最长上升子序列求长度

普通DP(复杂度O^2)

 1 #include <iostream>
 2 using namespace std;
 3 
 4 const int N = 1010;
 5 int a[N], dp[N], n;
 6 
 7 int main() {
 8     cin>>n;
 9     for(int i = 1; i <= n; i++)
10         cin>>a[i];
11 
12     for(int i = 1; i <= n; i++) {
13         dp[i] = 1; //子序列长度为1的情况
14         for(int j = 1; j < i; j++) //枚举ai之前的数
15             if(a[i] > a[j])
16                 dp[i] = max(dp[i], dp[j] + 1);
17     }
18 
19     int res = 0;
20     for(int i = 1; i <= n; i++)
21         res = max(res, dp[i]);
22 
23     cout<<res<<endl;
24     return 0;
25 }

二分DP(目前有问题,来日再来研究)

思路:

用 lis 数组储存 最长上升子序列的 序列 的最优情况 。

在大于lis [ len ]时 len++,在小于lis[ len ]时可以将arr[ i ]在 lis 中的数进行替换掉。所以此算法主要是在不停的找最合适的起点和最合适的终点。

举例:

输入数组:2 1 5 3 6 4 8 9 7  显而易见 答案为:5

以下是 lis 数组的变化情况 :

第一步:2                   替换

第二步:1                   替换

第三步:1 5                加入

第四步:1 3                替换

第五步:1 3 6             加入

第六步:1 3 4             替换

第七步:1 3 4 8           加入

第八步:1 3 4 8 9        加入

 第九步:1 3 4 7 9       替换     (这里是不是有问题??明明7在原序列中是在9的后面)

dp[i]表示长度为 i 的子序列中,末尾元素的最小值,且dp数组是严格单调增加的。枚举到第 j 个数时,如果 j 大于dp数组当前最大长度所对应的值,则说明 j 比当前上升子序列的末尾还大,那么就将 j 加入dp数组。如果 j 小于dp数组当前最大长度所对应的值,则说明加上 j 以后就不构成上升子序列了,需要在dp数组中找到第一个大于 j 的数,用 j 去替换它。由于dp数组始终是单调递增的,可以用二分法,最后dp数组的长度就是最长上升子序列长度。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 const int N = 100010;
 5 
 6 int a[N], dp[N], n, cnt;
 7 
 8 int find(int x) {
 9     int l = 1, r = cnt;
10     while(l < r) {
11         int mid = l + r >> 1;
12         if(dp[mid] >= x) r = mid;
13         else l = mid + 1;
14     }
15     return l;
16 }
17 int main() {
18     cin>>n;
19     for(int i = 1; i <= n; i++)
20         cin>>a[i];
21         
22     dp[++cnt] = a[1];
23     for(int i = 2; i <= n; i++) {
24         if(a[i] > dp[cnt]) {
25             dp[++cnt] = a[i];
26         }
27         else {
28             int t = find(a[i]);
29             dp[t] = a[i];
30         }
31     }
32     
33     cout<<cnt<<endl;
34     return 0;
35 }

原文链接:https://blog.csdn.net/Komatsu_1137/article/details/104356310

posted @ 2020-02-18 10:43  古比  阅读(520)  评论(0编辑  收藏  举报