一道线性动态规划的题 刚开始没看懂输入输出为啥能拦截6个导弹 后来才知道中间的导弹可以跳过 就是一个查找最长不升子序列
第二问也可以转化成最长升子序列
然后这道题就可以解了
#include<bits/stdc++.h>
using namespace std;
int n;
int len; //记录最长不升子序列即x数组的长度)
int a[100005]; //存所有的导弹
int x[100005]; //存当前拦截的导弹的高度
int main(){
while(scanf("%d",&a[++n])==1)
x[n]=1;
n--;
问题一
for(int i=1;i<=n;i++){
//可以拦截或x数组为空 直接加入x数组
if(len==0||a[i]<=x[len]) x[++len]=a[i];
//不可以拦截 二分查找可以替换的位置
else{
int l=1,r=len;
while(l<r){
int mid=(l+r)>>1;
if(a[i]>x[mid]) r=mid;
else l=mid+1;
}
x[l]=a[i]; //替换
}
}
printf("%d\n",len);
问题二
for(int i=1;i<=n;i++){
if(len==0||a[i]>x[len]) x[++len]=a[i];
else{
int l=1,r=len;
while(l<r){
int mid=(l+r)>>1;
if(a[i]<=x[mid]) r=mid;
else l=mid+1;
}
x[l]=a[i];
}
}
printf("%d\n",len);
return 0;
}