最长(不)上升子序列(LIS与LDS问题)
对于LIS,如果下一个数大于目前最长序列数的最后一位,则将最长序列数+1,反之则直接用lower_bound()进行二分查找,找到第一个大于等于这个数的序列数,将它替换,此替换过程不影响最长序列的个数。
同理,对于LDS,如果下一个数小于等于目前最长序列数的最后一位,则最长序列数+1,反之利用upper_bound()进行二分查找,找到第一个大于这个数的序列数将之替换。
代码如下:
b[0] = a[0]; //最长不上升子序列 for (int i = 1; i < cnt; i++) { if (b[cnt1] >= a[i]) b[++cnt1] = a[i];//序列向后移 else { int x = upper_bound(b, b + cnt1, a[i], greater<int>()) - b;//降序查找 b[x] = a[i];//找到第一个小于a[i],将它替换 } } memset(b, 0, sizeof(b)); b[0] = a[0]; //最长上升子序列 for (int i = 1; i < cnt; i++) { if (a[i] > b[cnt2]) b[++cnt2] = a[i];//序列向后移 else { int x = lower_bound(b, b + cnt2, a[i]) - b;//升序查找 b[x] = a[i];//找到第一个大于等于a[i],替换 } }

浙公网安备 33010602011771号