思路:用一数组dp[]维护需要系统的个数以及每套系统可以拦截的导弹的最低高度,显然dp[1] = a[1](a[]表示所有导弹),若一导弹的高度大于当前系统所达到的高度,则说明需要新加一个系统,值为当前导弹的高度,可以看出dp[j] > dp[i](0<i< j);若导弹的高度小于当前系统所达到的高度,说明该导弹可以被当前系统或之前的系统拦截,这时我们需要更新某一系统射击的高度,更新哪个呢,当然是射击高度大于该导弹的系统里的最小值的那个(很好理解吧)。由于dp[]是递增的,所以可以用二分查找。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1009;
int n, dp[N], a[N];
int bisearch(int val, int last) {
int l, r, mid;
l = 1;
r = last;
while (l <= r) {
mid = (l+r)>>1;
if (val >= dp[mid])
l = mid + 1;
else
r = mid - 1;
}
return l;
}
int LIS() {
int i, ans, pos;
dp[1] = a[1];
ans = 1;
for (i = 2; i <= n; ++i) {
if (a[i] >= dp[ans])
dp[++ans] = a[i];
else {
pos = bisearch(a[i], ans);
dp[pos] = a[i];
}
}
return ans;
}
int main()
{
int i;
while (scanf("%d", &n) != EOF) {
for (i = 1; i <= n; ++i)
scanf("%d", &a[i]);
printf("%d\n", LIS());
}
return 0;
}