Sloution :
对于问1: 求最长 下降子序列 (非严格)
对于问2: 求最长 上升子序列 (严格)
问2:
意思是,把一组序列,最少能拆成几个 不上升子序列
每一个较高的后面的导弹,都不能被前面的击中,也就是说,能够划分的个数 >= lis
画图说明 lis <= 能够划分的个数
故 lis = 能够划分的个数
#include <iostream>
#include <cstring>
#include <string>
#include<algorithm>
#include<cmath>
#define ll long long
#define PII pair<int, int>
#define _for(i, a, b) for (int i = a; i < b; i++)
#define For(i, a, b) for (int i = a; i <= b; i++)
#define foR(i, b, a) for (int i = b; i >= a; i--)
#define ms(a,b) memset(a, b, sizeof a)
#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) a / gcd(a, b) * b
using namespace std;
const int N = 1e5 + 10;
int k=1;
int a[N];
int f[N];
int de[N], in[N];
void lds(){
f[1] = a[1];
de[1] = 1;
For(i,2,k){
int pos = upper_bound(f + 1, f + 1 + k, a[i],greater<int>()) - f;
de[i] = pos;
f[pos] = max(f[pos], a[i]);
}
}
void lis(){
ms(f, 0x3f);
f[1] = a[1];
in[1] = 1;
For(i,2,k){
int pos = lower_bound(f + 1, f + 1 + k, a[i]) - f;
in[i] = pos;
f[pos] = min(f[pos], a[i]);
}
}
int main(){
while(cin>>a[k])
k++;
k--;
lds();
lis();
int a = de[1], b = in[1];
For(i, 2, k) a = max(a, de[i]);
For(i, 2, k) b = max(b, in[i]);
cout << a << endl
<< b;
}