### Algorithm training interceptor

Time limit: 1.0s memory limit: 256.0MB

### Problem description

In order to defend against the missile attack of the enemy, a kind of missile interception system has been developed. But this kind of missile intercepting system has a defect: although its first shell can reach any height, every shell in the future can not be higher than the height of the previous one. One day, the radar caught the enemy's missiles coming. Since the system is still in the pilot phase, there is only one system, so it may not be able to intercept all missiles.

Input the altitude of missiles in turn (the altitude data given by the radar is not more than 30000 positive integers), calculate the maximum number of missiles that this system can intercept, and the minimum number of such missile interception systems that are required to intercept all missiles.

### Input format

One line, which is the altitude of the missile in turn

### Output format

Two lines, respectively, are the maximum number of missiles to intercept and the minimum number of systems to intercept all missiles

### sample input

389 207 155 300 299 170 158 65

### sample output

6

2

Title: Brief

analysis: I feel that this problem cleverly combines these two seemingly identical algorithms, one is the longest non descending subsequence problem, the other is the longest ascending subsequence problem. Considering the meaning of the problem, it asks the minimum number of systems to be equipped. To be clear, it depends on how many "longest non ascending subsequences" you can find. If you invert the sequence, you can find the longest non descending subsequence It is just the largest number of the longest ascending subsequence. You can simulate it yourself

### N^2 writing

```
#include <bits/stdc++.h>
using namespace std;
int a[10010];
int len,res;
int up[10010],down[10010];
int main() {
string s;
getline(cin,s);
istringstream ss(s);
int x;
while(ss >> x) a[len++] = x;
int res_num = 0,res_cnt = 0;
for(int i = 0;i < len;i++) {
up[i] = down[i] = 1;
for(int j = 0;j < i;j++) {
if(a[i] <= a[j])
down[i] = max(down[i],down[j] + 1);
else {
up[i] = max(up[i],up[j] + 1);
}
}
res_cnt = max(res_cnt,up[i]);
res_num = max(res_num,down[i]);
}
cout<<res_num<<endl<<res_cnt<<endl;
return 0;
}
```

### nlogn writing

```
#include <bits/stdc++.h>
using namespace std;
int a[10010];
int b[10010];
int len1,len2,len;
int up[10010],down[10010];
int main() {
string s;
getline(cin,s);
istringstream ss(s);
int x;
while(ss >> x) a[len++] = x;
for(int i = len-1;i >= 0;i--) b[len-i-1] = a[i];
up[0] = a[0];
for(int i = 1;i < len;i++) {
if(a[i] > up[len1]) {
up[++len1] = a[i];
} else {
int t = lower_bound(up,up + len1,a[i]) - up;
up[t] = a[i];
}
}
down[0] = b[0];
for(int i = 1;i < len;i++) {
if(b[i] >= down[len2]) {
down[++len2] = b[i];
} else {
int t = upper_bound(down,down + len2,b[i]) - down;
down[t] = b[i];
}
}
cout<<len2+1<<endl<<len1+1<<endl;
return 0;
}
```

- If there is any mistake or omission, please talk about UP, ths in private