P1020 导弹拦截 (贪心+最长不降子序列)
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。输入输出格式
输入格式:
11行,若干个整数(个数\le 100000≤100000)
输出格式:
22行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
输入样例#1: 复制389 207 155 300 299 170 158 65
输出样例#1: 复制6
2
思路:第一问就是求最长不降子序列 第二问贪心
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<time.h> #include<queue> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1e9+7; int a[100007]; int l[100007]; int r[100007]; int ans1[100007]; int ans2[100007]; int main(){ ios::sync_with_stdio(false); int n=1; while(cin>>a[n])n++; n--; for(int i=1;i<=n;i++){ l[i]=a[i]; r[i]=a[n+1-i]; } int s1,s2; s1=s2=0; ans1[0]=ans2[0]=-inf; for(int i=1;i<=n;i++){ if(r[i]>=ans1[s1]){ ans1[++s1]=r[i]; }else{ int pos=upper_bound(ans1,ans1+s1,r[i])-ans1; ans1[pos]=r[i]; } } for(int i=1;i<=n;i++){ bool f=0; int minh=inf; int pos; for(int j=0;j<s2;j++){ if(l[i]<=ans2[j]&&minh>ans2[j]-l[i]){ minh=ans2[j]-l[i]; pos=j; f=1; } } if(!f){ ans2[s2]=l[i]; s2++; }else{ ans2[pos]=l[i]; } } cout<<s1<<endl<<s2<<endl; return 0; }

更多精彩