1、 题目先要输出数列的最长非上升子序列,套用模板 :LIS 模板就可。
先把数组 reverse 一下,在用 std::upper_bound
2、 加入 数组 h[] = {90, 103, 99, 83, 102, 70, 86, 70, 99, 71}
依次扫描,用若干条队列模拟 最长非上升子序列
首先 h[1] = 90 , 新建一条 队列,然后扫描 h[2] = 103 , 因为 103 > 90,
103 不能排在90所在的队列。 此时, 已经有 2 条队列
队列 1 : 90
队列 2 : 103
现在 h[3] = 99 要进入对应的队列, 需要用二分查找,找到目前所有队列中,
最后一个元素, 第一个 大于等于 99的队列的下标(显然是队列2), 99 插入队列2
然后 ,队列数据变为:
队列 1 : 90
队列 2 : 103, 99 // 用数组 last_h[i] 表示队列最后一个元素的值
显然 last_h[1] = 90, last_h[2] = 99, 现在 h[4] = 83 进队, 相应的变为:
队列 1 : 90, 83
队列 2 : 103, 99, //last_h[1] = 83, last_h[2] = 99,
然后 h[5] = 102 进队列, 二分查找 出来, 102 插入队列3 (新建一条队列)
按照这种方式,就可以算出,一共需要多少条队列,也就是导弹拦截系统
#include <bits/stdc++.h>
const int MaxN = 100010;
using namespace std;
int n, len;
int h[MaxN];
int d[MaxN];
void find_longest_sub_list()
{
reverse(h + 1, h + n + 1);
d[1