【NC16810】拦截导弹

题目

拦截导弹

贪心、二分

思路

这是一道求最长XX子序列的经典问题,其中XX表示【上升、下降、不上升、不下降】。
题目有两个问题,第一个问题很直接,就是求最长不上升子序列长度,但是第二个问题需要思考,要用到数学定理,不过为了简化问题,这里直接给出结论:第二问就是问最长上升子序列长度。

可以知道的是,求这类最长XX子序列的方法应该是相通的,可以互相转化。所以这里只记录求最长上升子序列长度的方法。

求最长上升子序列长度的方法有很多,动态规划理论上可行,但是时间复杂度为 O ( n 2 ) O(n^2) O(n2),在此题的 100000 100000 100000 的数据范围内显然不可行。然后有更优的解法:贪心+二分。这种方法的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),可以解决此题,本文记录的也是这种方法。

如何贪心+二分呢?这里直接给出算法。

  1. 记原数组为 a a a,设置一个辅助数组 b b b,初始化为正无穷
  2. 从左往右遍历数组 a a a,并对每一个元素 a [ i ] a[i] a[i],使用二分法找出数组 b b b 中第一个大于等于 a [ i ] a[i] a[i] 的下标 t t t,并使 b [ t ] = a [ i ] b[t]=a[i] b[t]=a[i]
  3. 最后数组 b b b 中不是正无穷的元素个数即为数组 a a a 的最长上升子序列的长度。

其余的最长XX子序列问题也可以触类旁通,这里不再赘述。

代码

#include <limits.h>
#include <stdio.h>
#define N 100005

void init(int* arr, int n) {
    for (int i = 0; i < n; i++) {
        arr[i] = INT_MAX;
    }
}

// 返回数组中第一个大于目标值的下标,没有则返回数组长度
int first_GT(int* arr, int n, int target) {
    int l = 0, r = n - 1, mid = 0;
    while (l <= r) {
        mid = ((r - l) >> 1) + l;
        if (arr[mid] > target) {
            if (!mid || arr[mid - 1] <= target) {
                return mid;
            } else {
                r = mid - 1;
            }
        } else {
            l = mid + 1;
        }
    }
    return n;
}

// 返回数组中第一个大于等于目标值的下标,没有则返回数组长度
int first_GE(int* arr, int n, int target) {
    int l = 0, r = n - 1, mid = 0;
    while (l <= r) {
        mid = ((r - l) >> 1) + l;
        if (arr[mid] >= target) {
            if (!mid || arr[mid - 1] < target) {
                return mid;
            } else {
                r = mid - 1;
            }
        } else {
            l = mid + 1;
        }
    }
    return n;
}

int main(void) {
    // 读入数据
    int a[N], n = 0;
    while (~scanf("%d", &a[n])) {
        n++;
    }
    // 建立辅助数组,全部置为最大值
    int b[N], i = 0, t = 0, len = 0;
    init(b, N);
    // 第一问是求最长不上升子序列长度,也就是倒过来的最长不下降子序列长度
    // 从右往左找最长不下降子序列
    for (i = n - 1; i >= 0; i--) {
        // 寻找b中第一个大于a[i]的下标
        t = first_GT(b, N, a[i]);
        if (t > len) len = t;
        // 将这个值替换为a[i]
        b[t] = a[i];
    }
    // 最后输出辅助数组中被更新的值的长度
    // 即为题目所求的能拦截导弹的数量
    printf("%d\n", len + 1);

    // 第二问求的是最长上升子序列长度
    // 首先将辅助数组重置
    init(b, N);
    len = 0;
    // 然后从左往右找最长上升子序列
    for (i = 0; i < n; i++) {
        // 寻找b中第一个大于等于a[i]的下标
        t = first_GE(b, N, a[i]);
        if (t > len) len = t;
        // 将这个值替换为a[i]
        b[t] = a[i];
    }
    // 最后输出辅助数组中被更新的值的长度
    // 即为题目所求的需要的最少导弹系统数量
    printf("%d\n", len + 1);
    return 0;
}

代码是用标准C语言写的,由于C语言并没有提供二分的API,所以只能自己手写,显得代码比较臃肿。其实笔者已经整理好了这类问题的C++模板,见关于O(nlogn)求最长(上升/不上升/下降/不下降)子序列的总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/578154.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

spring boot3单模块项目工程搭建-上(个人开发模板)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 目录 写在前面 上文衔接 常规目录创建 common目录 exception.handle目录 result.handle目录 controller目录 service目录 mapper目录 entity目录 test目录 写在最后 写在前面 本文…

CSS学习(选择器、盒子模型)

1、CSS了解 CSS&#xff1a;层叠样式表&#xff0c;一种标记语言&#xff0c;用于给HTML结构设置样式。 样式&#xff1a;文字大小、背景颜色等 p标签内不能嵌套标题标签。 px是相对于分辨率而言的&#xff0c; em是相对于浏览器的默认字体&#xff0c; rem是相对于HTML根元…

更易使用,OceanBase开发者工具 ODC 4.2.4 版本升级

亲爱的朋友们&#xff0c;大家好&#xff01;我们的ODC&#xff08;OceanBase Developer Center &#xff09;再次迎来了重要的升级V 4.2.4&#xff0c;这次我们诚意满满&#xff0c;从五个方面为大家精心打造了一个更加易用、贴心&#xff0c;且功能更强的新版本&#xff0c;相…

如何写好代码?

文章目录 前言内容代码应当易于理解命名注释格式循环和逻辑设计函数设计类其它&#xff08;编程规范、静态检查工具&#xff09;重构 前言 在软件开发领域&#xff0c;写好代码是至关重要的一环。不论是在学校学习的学生&#xff0c;刚刚毕业的应届生&#xff0c;还是刚步入企…

JAVA SWING JTABLE表格,点击表头数据可以排序,且第一二行位置固定,不参与排序

对于JAVA SWING 界面开发&#xff0c;使用表格JTABLE开发过程中&#xff0c;一些情况下可能需要在点击表头时对数据进行排序处理。对于简单的排序处理&#xff0c;jtable的setAutoCreateRowSorter方法可满足&#xff0c;但是对于高要求的排序&#xff0c;则满足不了。 比如&am…

《html自用使用指南》--基于w3School实践

1.基础标签 文本输入时&#xff0c;在编辑器中的换行&#xff0c;多个空格&#xff0c;都被编辑器看作一个空格 <p> 这个段落 在源代码 中 包含 许多行 但是 浏览器 忽略了 它们。 </p>结果&#xff1a;这个段落 在源代码 中 包含 许多行 但是 浏览器…

惊!文件夹突变文件,揭秘背后原因及数据恢复秘籍

在使用电脑时&#xff0c;我们有时会遇到一些意想不到的问题。比如&#xff0c;你可能会突然发现&#xff0c;原本存储着大量重要资料的文件夹&#xff0c;竟然变成了一个无法打开的文件。这种情况听起来可能有些匪夷所思&#xff0c;但它确实存在&#xff0c;且给用户带来了巨…

微信收款码0.2费率开通

很多人想申请低手续费率的收款码不知从何下手&#xff0c;在参考了大量博客教学之后&#xff0c;终于搞懂了详细流程以及注意事项。在此记录一下。我申请的是一个只需要0.2%费率的微信收款码&#xff0c;申请时间是2022年2月12日。申请之前只需要准备营业执照和法人身份z&#…

用不了ChatGPT?快试试免费又强大的Anthropic Claude

一、Claude 简介 Anthropic 官方&#xff1a; https://www.anthropic.com/product Claude 是最近新开放的一款 AI 聊天机器人&#xff0c;是世界上最大的语言模型之一&#xff0c;比之前的一些模型如 GPT-3 要强大得多&#xff0c;因此 Claude 被认为是 ChatGPT 最有力的竞争…

25计算机考研院校数据分析 | 南京大学

南京大学&#xff08;Nanjing University&#xff09;&#xff0c;简称“南大”&#xff0c;是中华人民共和国教育部直属、中央直管副部级建制的全国重点大学&#xff0c;国家首批“双一流”、“211工程”、“985工程”重点建设高校&#xff0c;入选首批“珠峰计划”、“111计划…

Perfectly Clear Workbench for mac/win:让图像清晰不再是难题

在数字时代&#xff0c;图像处理已经成为我们日常生活和工作中的必备技能。无论是专业摄影师&#xff0c;还是业余爱好者&#xff0c;都渴望拥有一款能够轻松提升图像质量的软件。今天&#xff0c;我要向大家推荐一款卓越的图像清晰处理软件——Perfectly Clear Workbench&…

NAT网络地址转换实验(华为)

思科设备参考&#xff1a;NAT网络地址转换实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 NAT&#xff08;Network Address Translation&#xff09;&#xff0c;即网络地址转换技术&#xff0c;是一种在现代计算机网络中广泛应用的技术&#xff0c;主要用于有效管…

将游戏界面与注册/登录界面连接到一起

一、 导包 在注册页面中导入一个import subprocess包 二、 使用代码将其连接到一起 在循环中加入下面这一行代码&#xff0c;用来实现效果 subprocess.run(["python", "game代码.py"]

容器安全-镜像扫描

前言 容器镜像安全是云原生应用交付安全的重要一环&#xff0c;对上传的容器镜像进行及时安全扫描&#xff0c;并基于扫描结果选择阻断应用部署&#xff0c;可有效降低生产环境漏洞风险。容器安全面临的风险有&#xff1a;镜像风险、镜像仓库风险、编排工具风险&#xff0c;小…

【图解计算机网络】TCP协议三次握手与四次挥手

TCP协议三次握手与四次挥手 三次握手流程为什么是三次握手&#xff0c;而不是两次或四次四次挥手流程TIME_WAIT 为什么要等待 2MSL为什么握手是三次&#xff0c;挥手是四次&#xff1f; 三次握手流程 首先是客户端&#xff08;也就是我们的浏览器&#xff09;发送一个SYN标志位…

在Jupyter notebook中添加虚拟环境

通常我们打开Jupyter notebook&#xff0c;创建一个新文件&#xff0c;只有一个Python3&#xff0c;但是我们也会想使用自己创建的虚拟环境&#xff0c;很简单仅需几部即可将自己的conda环境添加到jupyter notebook中。 1. 创建并激活conda环境&#xff08;已有可跳过&#xf…

Datasophon1.2.1集成Dinky1.0.1

Dinky 下载地址: https://github.com/DataLinkDC/dinky/releases/tag/v1.0.1 Dinky 官网&#xff1a;https://www.dinky.org.cn/ 1.下载Dinky wget https://github.com/DataLinkDC/dinky/releases/download/v1.0.1/dinky-release-1.16-1.0.1.tar.gz mv dinky-release-1.16-1.…

selenium入门篇(环境搭建、八大定位)

背景 Web自动化测现状 1. 属于 E2E 测试 2. 过去通过点点点 3. 好的测试&#xff0c;还需要记录、调试网页的细节 一、selenium环境搭建 一键搭建 pip3 install webdriver-helper 安装后自动的完成&#xff1a; 1. 查看浏览器的版本号 2. 查询操作系统的类型 …

SOLIDWORKS Electrical 3D--精准的三维布线

相信很多工程师在实际生产的时候都会遇到线材长度不准确的问题&#xff0c;从而导致线材浪费甚至整根线材报废的问题&#xff0c;这基本都是由于人工测量长度所导致的&#xff0c;因此本次和大家简单介绍一下SOLIDWORKS Electrical 3D布线的功能&#xff0c;Electrical 3D布线能…

EasyV的可视化作品,没有对这行深入理解,搞不了如此漂亮。

EasyV是我非常佩服的一家可视化服务商&#xff0c;作品涉猎广泛&#xff0c;经典而大气&#xff0c;贝格前端工场的可视化业务与之相比&#xff0c;还是有一定差距&#xff0c;向行业头部企业学习&#xff0c;分享出来一些给大家看下。