动态规划入门 洛谷P1020 拦截导弹

来源:互联网 发布:linux shell 打印变量 编辑:程序博客网 时间:2024/05/21 12:45
P1020 导弹拦截

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入输出格式

输入格式:

 

一行,若干个正整数最多100个。

 

输出格式:

 

2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

 

输入输出样例

输入样例#1:
389 207 155 300 299 170 158 65
输出样例#1:
62


需要知道一个叫做偏序集的没用的鬼东西
引入偏序关系,它是指在集合A上的二元关系≤(“≤”这是一个抽象符号,与大于小于无关联),满足自反性、反对称性和传递性

经过乱七八糟难以理解的推理
得出以下结论
给定序列A,最少用A的最长不上升子序列长度个上升子序列覆盖它
233......绕口


贴代码
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n; 7 int num1[10010],num2[10010]; 8 int top1,top2; 9 int tmp;10 11 void add1(int t){12     if(t<num1[top1]) num1[++top1]=t;13     else{14         int ll=1;15         int rr=top1;16         int mid;17         while(ll<=rr){18             mid=(ll+rr)>>1;19             if(t<=num1[mid]) ll=mid+1;20             else rr=mid-1;//注意-1和+121         }22         num1[ll]=t;23     }24     return;25 }26 27 void add2(int t){28     if(t>num2[top2]) num2[++top2]=t;29     else{30         int ll=1;31         int rr=top2;32         int mid;33         while(ll<=rr){34             mid=(ll+rr)>>1;35             if(t>num2[mid]) ll=mid+1;36             else rr=mid-1;//注意-1和+137         }38         num2[ll]=t;39     }40     return;41 }42 43 int main(){44     num1[0]=0x3f3f3f3f;45     num2[0]=-1;46     while(scanf("%d",&tmp)!=EOF) add1(tmp),add2(tmp);47     printf("%d\n%d",top1,top2);48     return 0;49 }