洛谷 P1020 [NOIP1999 普及组] 导弹拦截(最长上升子序列,贪心,二分查找)

1、 题目先要输出数列的最长非上升子序列,套用模板 :LIS 模板就可。
	先把数组 reverse 一下,在用 std::upper_bound
2、 加入 数组 h[] = {90, 103, 99, 83, 102, 70, 86, 70, 99, 71}
	依次扫描,用若干条队列模拟 最长非上升子序列
	首先 h[1] = 90 , 新建一条 队列,然后扫描 h[2] = 103 , 因为 103 > 90,
	103 不能排在90所在的队列。 此时, 已经有 2 条队列
	队列 1 : 90
	队列 2 : 103

现在 h[3] = 99 要进入对应的队列, 需要用二分查找,找到目前所有队列中,
最后一个元素, 第一个 大于等于 99的队列的下标(显然是队列2), 99 插入队列2
然后 ,队列数据变为:
队列 1 : 90
队列 2 : 103, 99		// 用数组 last_h[i] 表示队列最后一个元素的值

显然 last_h[1] = 90, last_h[2] = 99, 现在 h[4] = 83 进队, 相应的变为:
队列 1 : 90, 83		
队列 2 : 103, 99,  		//last_h[1] = 83, last_h[2] = 99,

然后 h[5] = 102 进队列, 二分查找 出来, 102 插入队列3 (新建一条队列)
按照这种方式,就可以算出,一共需要多少条队列,也就是导弹拦截系统
#include <bits/stdc++.h>
const int MaxN = 100010;
using namespace std;
int n, len;
int h[MaxN]; 	//导弹的高度
int d[MaxN];	//d[k] 表示长度是k 的不降序子序列末尾元素的最大值

void find_longest_sub_list()
{
   
	reverse(h + 1, h + n + 1);
	d[1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值