P1020 導彈攔截 鏈接:https://www.luogu.org/problemnew/show/P1020 題意:某導彈攔截系統,它每次所攔截的導彈高度均不能超過前一次所攔截的高度(第一次可以達到任意高度),求該系統最多能攔截幾枚導彈以及最少需要多少個這樣的系統才能攔截所有的導彈。 思路:最 ...
P1020 導彈攔截
鏈接:https://www.luogu.org/problemnew/show/P1020
題意:某導彈攔截系統,它每次所攔截的導彈高度均不能超過前一次所攔截的高度(第一次可以達到任意高度),求該系統最多能攔截幾枚導彈以及最少需要多少個這樣的系統才能攔截所有的導彈。
思路:最長不上升子序列+最長上升子序列
最長不上升子序列用來求該系統最多能攔截幾枚導彈,最長上升子序列用來求需要幾個系統才能攔截所有的導彈。
為什麼會是最長上升子序列?我打個比方,突然有一個導彈的高度大於你當前的攔截最大高度,你肯定攔截不了,所以你肯定需要再來一個系統才能攔截下來。所以只需求最長上升子序列的長度即是需要的系統數量。
代碼:(寫的比較醜。。。。)
#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; }