当前位置: 代码迷 >> 综合 >> 1010. 拦截导弹
  详细解决方案

1010. 拦截导弹

热度:78   发布时间:2024-01-17 14:11:15.0

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。

但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。

某天,雷达捕捉到敌国的导弹来袭。

由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,导弹数不超过1000),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

共一行,输入导弹依次飞来的高度。

输出格式

第一行包含一个整数,表示最多能拦截的导弹数。

第二行包含一个整数,表示要拦截所有导弹最少要配备的系统数。

数据范围

雷达给出的高度数据是不大于 30000 的正整数,导弹数不超过 1000。

输入样例:
389 207 155 300 299 170 158 65
输出样例:
6
2
代码1:
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N];
int n = 1;
int d[N];// 辅助数组
int main()
{while (cin >> a[n])n++;n--;int len = 1;//最长非上升子序列长度 贪心和dp都能做reverse(a + 1, a + 1 + n);d[1] = a[1];for (int i = 2; i <= n; i++){int j = upper_bound(d + 1, d + 1 + len, a[i]) - d;d[j] = a[i];if (j > len)len = j;}cout << len << endl;//非上升子序列覆盖个数==最长上升子序列长度reverse(a + 1, a + 1 + n);set<int> st;for (int i = 1; i <= n; i++){int temp = a[i];if (st.size() && temp < *st.rbegin())st.erase(*(st.lower_bound(temp)));st.insert(temp);}cout << st.size();return 0;
}
代码2:
//纯STL
#include <bits/stdc++.h>
using namespace std;int main()
{int n;int temp;vector<int> ve;while (cin >> temp)ve.push_back(temp);multiset<int> st1;n = ve.size();for (int i = n - 1; i >= 0; i--){temp = ve[i];if (st1.size() && temp < *st1.rbegin())st1.erase((st1.upper_bound(temp)));st1.insert(temp);}cout << st1.size() << endl;set<int> st;for (int i = 0; i < n; i++){temp = ve[i];if (st.size() && temp < *st.rbegin())st.erase(*(st.lower_bound(temp)));st.insert(temp);}cout << st.size();return 0;
}