P1020 导弹拦截c++
连接:https://www.luogu.org/problemnew/show/P1020spa
题意:某导弹拦截系统,它每次所拦截的导弹高度均不能超过前一次所拦截的高度(第一次能够达到任意高度),求该系统最多能拦截几枚导弹以及最少须要多少个这样的系统才能拦截全部的导弹。code
思路:最长不上升子序列+最长上升子序列blog
最长不上升子序列用来求该系统最多能拦截几枚导弹,最长上升子序列用来求须要几个系统才能拦截全部的导弹。ci
为何会是最长上升子序列?我打个比方,忽然有一个导弹的高度大于你当前的拦截最大高度,你确定拦截不了,因此你确定须要再来一个系统才能拦截下来。因此只需求最长上升子序列的长度便是须要的系统数量。get
代码:(写的比较丑。。。。)it
#include<bits/stdc++.h> using namespace std; #define maxn 100005 int n,num; int a[maxn]; int dp1[maxn]; int dp2[maxn]; struct cmp{ bool operator()(int a,int b){return a>b;} }; int main() { n=1; while(cin>>a[n])n++; n--; if(n==0) { cout<<0<<endl<<0<<endl; return 0; } dp1[1]=a[1]; dp2[1]=a[1]; int len1=1,len2=1; for(int i=2;i<=n;i++) { if(a[i]<=dp1[len1])dp1[++len1]=a[i]; else { int j=upper_bound(dp1+1,dp1+len1+1,a[i],cmp())-dp1; dp1[j]=a[i]; } if(a[i]>dp2[len2])dp2[++len2]=a[i]; else { int j=lower_bound(dp2+1,dp2+len2+1,a[i])-dp2; dp2[j]=a[i]; } } cout<<len1<<endl<<len2<<endl; return 0; }