题目:[NOIP1999]拦截导弹
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入格式
输入数据为两行,
第一行为导弹的数目N(n<=1000)
第二行导弹依次飞来的高度,所有高度值均为不大于30000的正整数。
输出格式
输出只有一行是这套系统最多能拦截的导弹数和要拦截所有导弹最少要配备这种导弹拦截系统的套数。两个数据之间用一个空格隔开.
题解:
动归+贪心
代码实现:
#include<iostream> #include<cstring> using namespace std; int a[1001],b[1001],n,ans=0; void quicksort(int *d,int l,int r){ if(l>=r) return ; int i,j,k; k=d[l+rand()%(r-l+1)]; i=l;j=r; while(i<=j){ while(d[i]>k) i++; while(d[j]<k) j--; if(i<=j) {swap(d[i],d[j]);i++;j--;} } quicksort(d,i,r); quicksort(d,l,j); } void find(){ int i,j; b[1]=a[1]; for(i=2;i<=n;i++) { quicksort(b,1,ans+1); bool p=1; for(j=ans+1;j>=1;j--) if(b[j]>=a[i]) {p=0;b[j]=a[i];break;} if(p==1) {ans++;b[ans+1]=a[i];} } } int main() { int i,j; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=n;i++) { b[i]=1; for(j=1;j<i;j++) if(a[i]<=a[j]&&b[i]<b[j]+1) b[i]=b[j]+1; } int max=0; for(i=1;i<=n;i++) if(b[i]>max) max=b[i]; cout<<max<<" "; find(); cout<<ans+1<<endl; return 0; }