[DP动态规划]导弹拦截 - 1999年NOIP普及组

——写给和我一样的DP初学者

题目

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数):1)计算这套系统最多能拦截多少导弹;2)如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入

只有一行数据,包括若干以空格分隔的正整数,表示来袭的导弹的高度. 总共不超过350个数字。

输出

第一行只有一个正整数,表示最多能拦截的导弹数; 第二行也只有一个正整数,表示要拦截所有导弹最少要配备的系统数。

样例输入

8
389 207 155 300 299 170 158 65

样例输出

6
2

解题思路

对于“最多可以拦截多少导弹”这个问题毫无疑问是最长不上升子序列,代码可以参考DP基础题中的最长上升子序列

对于“最少需要多少套系统”这个问题就略微会显得有些棘手,但其实只是求最长上升子序列。不理解?我们举个栗子。

鞠躬尽瘁,哦不打错了,举个栗子

如上图,我们取深色标记的这个最长上升子序列,即a[2]与a[4]。

显而易见,拦截第二枚导弹的拦截系统一定不能拦截第四枚导弹,因为2 < 4并且a[2] > a[4],也就是说要是想要拦截下a[2]与a[4]这两枚导弹的话就至少需要两套导弹拦截系统。

同理我们也可以得出,拦截任意一条最长上升子序列的任意一枚导弹的导弹拦截系统一定不能拦截这条子序列中的另外任意一枚导弹。也就是说如果要拦截这条最长上升子序列里的所有导弹的话,至少需要的系统数等于这条子序列的长度。

所以说第二问我们求的“最少需要的系统数量”实际上就是求导弹高度的最长上升子序列的长度。这个长度就是我们所需要的系统数量。所以我们只需要求最长上升子序列的长度即可。

一段故事

这道题我整整做了一下午,一开始第二问使用贪心做的,然后不知道为什么不是RE就是WA,然后就去思考动态规划怎么解,然后想到下课都没有头绪。。。

最后旁边的xay说了一句,第二问就是求最长上升子序列呀,

我顿悟。。。

然后熬夜去把代码打了出来,顺便注册了个CSDN的号,然后写了这篇博客。。。

orz.


版权声明:本文为memset0原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。