[AcWing] 1010. 拦截导弹(C++实现)最长上升子序列模型+贪心
1. 题目
2. 读题(需要重点注意的东西)
读题:
每来一个导弹有两种选择:
-
接在现有某个导弹拦截系统之后
-
创建一个新的导弹拦截系统
我们希望一个导弹拦截系统拦截的导弹足够的多
(贪心
),那么如果要将这个导弹加到某一个导弹拦截系统之后的话,我们需要从现有的所有导弹拦截系统中,找到一个结尾大于当前导弹高度的最小的数
;如当前导弹高度为 200,现有系统如下:
-
系统1:500 300
210
-
系统2:450 350
220
-
系统3:400 380
230
-
系统4:400 380
199
210是结尾大于200的最小的数
,我们就要将它加到210
的后面,也就是加到系统1中,即:
- 系统1:500 300 210
200
思路:
最长上升子序列
+ 贪心
本题有两问:
第一问就是求最长上升子序列
第二问是求需要多少个导弹拦截系统:
-
如果当前导弹的高度能放到某个系统后(找到一个
结尾大于当前导弹高度的最小的数
),则放在其系统后; -
如果所有的结尾都小于当前的导弹高度,则开一个新的系统
优化: 从前往后枚举所有子序列的结尾,因为子序列的结尾的数是单调上升的,所以只要枚举到比自己大的第一个数就可以直接替换掉这个比自己大的数
3. 解法
---------------------------------------------------解法---------------------------------------------------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader