首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >计算大数组中从[currPos]到[currPos - k]的最大值

计算大数组中从[currPos]到[currPos - k]的最大值
EN

Stack Overflow用户
提问于 2014-06-21 11:04:52
回答 1查看 184关注 0票数 6

我正在为ACM比赛做准备,我被这个问题困住了。

你有一个给定位置的建筑物,,Xi,,,,盾牌是用钢做的,它们需要至少有两个高度相同的建筑物支撑。防护罩的右端必须位于某座建筑物的顶部。所有位于盾牌下的建筑物(包括那些躺在最后的建筑物)都受到该盾牌的保护,其高度不能超过设置盾牌的高度。一个建筑物最多可以用一个盾牌来保护。 给你无限数量的盾牌,每个盾牌长度相同。找出可以被盾牌保护的建筑物的最大数量,并找到可以用来保护最大建筑数量的最小的盾牌数目。 输入 第一行输入包含一个正整数T (1 <= T <= 20),测试用例数。 每个测试用例都从一个包含两个整数的行开始:建筑物数N (2 <= N <= 100,000)和屏蔽L的长度(1 <= L <= 1,000,000,000)。在接下来的N行中,每一行都有两个整数,Xi (第一层建筑的位置,0 <= Xi <= 1,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000)。这些建筑物按x坐标进行排序。不会有两座具有相同x坐标的建筑物。 输出 对于每个测试用例,在两条线上,输出可覆盖的最大建筑物数和可用于此目的的最小屏蔽数。

示例

代码语言:javascript
运行
复制
Input
17 3
1 2
2 1
3 2
4 3
5 1
6 2
7 4
8 2
9 3
10 4
11 2
15 2
16 1
17 3
18 3
19 1
20 2

Output
11 3

Explanation:
first shield: 1,2,3 
second shield: 7,8,9,10
third shield:  15,16,17,18

显然,蛮力解决方案很容易编写代码,但会在时间限制(1s)上失败,我读过关于段树的文章,但由于我没有使用段树,所以我感兴趣的是解决这个问题的方法,还是我忽略了一些更简单的解决方案?

虽然它说盾牌长度是L,但实际上是L+1,最后一栋建筑必须是最高的,并且有一座建筑在位置为Xi-1,西安-L具有相同的高度才能放置一个盾牌,建筑的位置将被分类。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-21 13:24:04

求出从pos - kpos的最大值也称为“滑动窗口最大问题”,它有一个简单的O(N)解决方案,不需要分段树或任何其他高级数据结构。

该算法如下:

1)让我们维护一个对的deque<value, position>

2)移动窗口边界的方式如下(这里使用伪代码):

代码语言:javascript
运行
复制
//Moving the right border.
right <- right + 1
cur <- pair<value[right], x[right]>
while not deque.empty and deque.back.value < cur.value
    deque.pop_back()
deque.push_back(cur)

//Moving the left border.
left <- left + 1
while deque.front.position is out of [x[left], x[right]] bounds
    deque.pop_front()

3)最大值仅为deque.front.value

该算法的复杂性是O(N),因为每个元素只被推到deque上一次,并且只从deque中删除一次(伪代码中的while循环的每一次迭代都会从deque中删除一个元素)。

现在,关于屏蔽的原始问题的解决方案:

1)让我们假设dp[pos] =所覆盖的建筑物的pair的最小数目,这样所有盾牌的右边框都是<= pos

2)让我们维护两个指针lowhighhigh是当前建筑物的指针,low指针是指向最左边的建筑物的指针,例如x[high] - x[low] >= L

3)high指针在for循环中总是以1递增,low指针被适当地调整(以满足2)属性。

4)然后可以按以下方式计算dp:对于high的固定值,dp[high]要么是dp[high - 1],要么是dp[low - 1] + high - low + 1(第二个只有在可以从lowhigh的屏蔽时才使用)。

5)如何检查是否可以放置盾牌?使用滑动窗口最大算法,可以在[low; high - 1]范围内保持最大值,并检查它是否等于H[high]

6)答案是dp[N - 1](基于0的指数化)。

该解决方案的复杂度为O(N),因为lowhigh总是递增,且不能超过N次数,而且滑动窗口的最大算法复杂度在上面给出了显示。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24340967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档