【问题描述】 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷: 虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天, 雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截 所有的导弹。输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数): 计算这套系统最多能拦截多少导弹; 【输入格式】 输入文件missile.in只有一行数据,包括若干以空格分隔的正整数,表示来袭的导弹的高度. 【输出格式】 输出文件missile.out只有一个正整数,表示最多能拦截的导弹数; 【输入样例】 389 207 155 300 299 170 158 65 【输出样例】 6#include<cstdio> #include<iostream> using namespace std; int h[22],f[22],g[22]; /** h[i]记录敌国的第i颗导弹高度 */ /** f[i]记录到第i颗导弹来时最多能拦截多少导弹*/ /** g[i]记录到第i颗导弹来时最多需要多少套系统*/ int n;/**记录有多少颗敌国导弹*/ int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int i,j,ans1,ans2; while(scanf("%d",&n)!=-1)/**循环读入数据直到文件结束*/ { for(i=1;i<=n;++i)/**读入n个高度并赋初值*/ { scanf("%d",&h[i]); f[i]=g[i]=1;/**f[i]至少可以拦截当前的一颗导弹,g[i]表示需要一套系统来拦截当前导弹*/ } ans1=0;/**记录当前知道最多可以拦截的数量*/ for(i=1;i<=n;++i)/**枚举每颗导弹来临*/ { for(j=1;j<i;++j)/**枚举第i颗导弹前的所有导弹*/ if(h[j]>=h[i])/**如果第j颗导弹的高度>=第i颗,说明拦截j后还能拦截i*/ f[i]=max(f[i],f[j]+1); /**与f[j]+1(表示拦截j后再拦截i这种方案最多能拦截的导弹数量)的值比较,更新f[i]的值*/ ans1=max(ans1,f[i]);/**维护ans1始终保存最大数量*/ } ans2=0;/**记录当前知道最多需要系统的数量*/ for(i=1;i<=n;++i)/**枚举每颗导弹来临*/ { for(j=1;j<i;++j)/**枚举第i颗导弹前的所有导弹*/ if(h[j]<h[i])/**如果第j颗导弹的高度<第i颗,说明拦截j后i就不能被拦截了*/ g[i]=max(g[i],g[j]+1); /**与f[j]+1(表示拦截j后再拦截i这种方案最多需要系统的数量)的值比较,更新g[i]的值*/ ans2=max(ans2,g[i]);/**维护ans2始终保存最大数量*/ } printf("%d,%d",ans1,ans2-1);/**输出答案*/ } return 0; }
NOIP 1999 导弹拦截 (最长不下降子序列)
最新推荐文章于 2024-07-20 09:09:25 发布