P1020 导弹拦截(洛谷)
这道题是dp题,LIS题目。
这道题跟HDU的1257一样的,不过这个题目输出的东西多一些。
要求最少的导弹拦截系统和最长的导弹拦截系统可以拦多少个导弹。
这个题目使用O(N^2)会WA。只能过一半
主要还是lower_bound和upper_bound的使用。
对于最少的导弹拦截系统,我们求LIS即可。
对于最长的导弹拦截系统可以拦多少个导弹,我们可以从后往前求最长的非递减的子序列。
因为这样反过来就是我们的最长的啦
注意是upper_bound哦~
代码部分:
#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e5 + 10;
int dp[N];
int a[N];
int cnt[N];
int n;
int main()
{
int ans1 = 0;
int ans2 = 0;
while (~scanf ("%d", &a[n++]) && a[n - 1]);
n--;
dp[0] = a[n - 1];
for (int i = n - 2; i >= 0; i--)
{
if (a[i] >= dp[ans1])
{
dp[++ans1] = a[i];
}
else
{
int t = upper_bound(dp, dp + ans1 + 1, a[i]) - dp;
dp[t] = a[i];
}
}
mst(dp, 0);
dp[0] = a[0];
for (int i = 1; i < n; i++)
{
if (a[i] > dp[ans2])
{
dp[++ans2] = a[i];
}
else
{
int t = lower_bound(dp, dp + ans2 + 1, a[i]) - dp;
dp[t] = a[i];
}
}
cout << ans1 + 1 << endl;
cout << ans2 + 1 << endl;
return 0;
}