首页 新闻 会员 周边 捐助

求助洛谷P1020!!!

-2
悬赏园豆:20 [已解决问题] 解决于 2024-02-04 22:08

[NOIP1999 普及组] 导弹拦截

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

一行,若干个整数,中间由空格隔开。

输出格式

两行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

样例 #1

样例输入 #1

389 207 155 300 299 170 158 65

样例输出 #1

6
2

提示

对于前 $50%$ 数据(NOIP 原题数据),满足导弹的个数不超过 $10^4$ 个。该部分数据总分共 $100$ 分。可使用$\mathcal O(n^2)$ 做法通过。
对于后 $50%$ 的数据,满足导弹的个数不超过 $10^5$ 个。该部分数据总分也为 $100$ 分。请使用 $\mathcal O(n\log n)$ 做法通过。

对于全部数据,满足导弹的高度为正整数,且不超过 $5\times 10^4$。

此外本题开启 spj,每点两问,按问给分。


$\text{upd 2022.8.24}$:新增加一组 Hack 数据。

深秋晨风的主页 深秋晨风 | 初学一级 | 园豆:51
提问于:2023-07-16 15:46
< >
分享
最佳答案
1

洛谷P1020题目是一个经典的动态规划问题,可以使用贪心策略来解决。

思路如下:

创建一个空数组 missiles 来存储导弹的高度。
读入导弹的高度,并将其添加到 missiles 数组中。
创建一个空数组 dp 来存储每个位置上的最长不上升子序列的长度。
遍历 missiles 数组,对于每个导弹的高度,将其插入到 dp 数组中适当的位置,并更新 dp 数组。
如果导弹的高度大于等于 dp 数组的最后一个元素,将其添加到 dp 数组末尾。
否则,在 dp 数组中使用二分查找找到第一个大于等于该导弹高度的位置,并将该位置的元素替换为导弹高度。
最终 dp 数组的长度即为能够拦截的最多导弹数目。
为了拦截所有的导弹,最少需要配备的拦截系统数目等于导弹总数减去能够拦截的最多导弹数目。
下面是一个示例的Python代码实现:

python
Copy code
missiles = list(map(int, input().split()))

dp = []
for h in missiles:
if not dp or h >= dp[-1]:
dp.append(h)
else:
left, right = 0, len(dp) - 1
while left < right:
mid = (left + right) // 2
if dp[mid] >= h:
left = mid + 1
else:
right = mid
dp[left] = h

max_intercept = len(dp)
min_systems = len(missiles) - max_intercept

print(max_intercept)
print(min_systems)
希望这个解法能够帮助到您解决洛谷P1020题目。如果您有任何疑问,请随时向我提问。

收获园豆:10
Technologyforgood | 大侠五级 |园豆:7541 | 2023-07-17 22:31
其他回答(2)
0

示例代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> heights; // 存储导弹高度的数组
    int height;
    while (cin >> height) {
        heights.push_back(height);
    }

    int maxCount = 0; // 最多能拦截的导弹数量
    int minSets = 0; // 最少需要配备的拦截系统数量

    vector<int> dp; // 动态规划数组,用于记录当前高度的最长递减子序列长度

    for (int i = 0; i < heights.size(); i++) {
        height = heights[i];

        auto it = lower_bound(dp.begin(), dp.end(), height); // 使用二分查找找到当前高度在dp数组中的位置

        if (it == dp.end()) {
            dp.push_back(height); // 当前高度比之前所有导弹的高度都大,所以将其插入dp数组中
            minSets++; // 需要增加一个新的拦截系统
        } else {
            *it = height; // 更新dp数组中的值
        }

        maxCount = max(maxCount, int(dp.size())); // 更新最多能拦截的导弹数量
    }

    cout << maxCount << endl;
    cout << minSets << endl;

    return 0;
}
收获园豆:10
lanedm | 园豆:2396 (老鸟四级) | 2023-07-17 10:18
0

怎么结束帖啊?

深秋晨风 | 园豆:51 (初学一级) | 2024-02-04 22:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册