最长子序列模型二(二分优化版)

news/2024/10/27 17:03:09/

文章目录

  • 提高课题解
    • 一、拦截导弹
    • 二、导弹防御系统
    • 三、最长公共上升子序列
    • 四、二分函数速写
  • 基础课题解
    • 五、最长上升子序列 II

提高课题解

一、拦截导弹

题目链接
在这里插入图片描述

第一问非常简单,直接用之前最长上身子序列模板就行
第二问就有难度了,我们要用最少的递减子序列覆盖这个数组,怎么样才最少呢?

把i这个位置放在在i位置之前的所有非递增子序列中的最后一个数大于等于第i个位置的数的非递增子序列,同时我们要放在所有大于等于i位置数的最小那一个的后面,这样才能保证i后面状态的位置能够有更多机会加入到前面的非递增子序列中,如果i这个状态都大于前面所有非递增子序列的最后一个数,那么我们要新开辟一个空间给i状态,因为它不满住前面所有的状态

图解:
在这里插入图片描述

在所有最后一个数大于等于i这个位置数的非递增子序列中,i这个位置的数一定要放在这些非递增子序列中最后一个数中最小的那个数?(这里要用贪心证明,证明见acwing彩色铅笔,我这里用个通俗的例子来说明)

见图:
在这里插入图片描述

二、导弹防御系统

题目链接
在这里插入图片描述

这个题也是经典的dp思想,运用dfs然后剪枝,你的第i个位置的状态要么放到递增子序列里面,要么放在递减子序列里面。

图解:为什么要恢复现场?
在这里插入图片描述

这里ans每次有一个结果出现也就是t == n的时候,每次都会更新一下ans(除非比ans小才会更新),ans维护的是所有状态的值,所以我们可以得到最小值

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 55;
int n;
int q[N];
int up[N], down[N];
int ans;void dfs(int u,int d,int t)
{if(u + d >= ans) return;//如果某一个方案的u + d//大于等于之前已有方案的总个数//,那么把这个方案pass掉if(t == n){if(ans > u + d) ans = u + d;//每次有比原有的最小方案小的方案,那么更新一下ansreturn;//更新完就返回}//两种策略,你这个数要么放在递增子序列里面,//要么放在递减子序列里面,这样就考虑比较全,不会漏掉某一个方案//如果你放在递增序列里面,这里默认up是递增子序列,因为每次你要加入新数的时候,//你要找所有小于新数的的数中最大的一个数,//这样能保证你后面新加的数有更多的机会放入up序列中//假设你放入的的是小于新数中最小的那一个数,//那么后面来了一个新数,比原来前面的新数把所有小于新数的的数中最小的一个数大//但是没有你倒数第二大的数小,那么你又重新开一个序列(这不是纯纯浪费了吗?)int i;for(i = 1;i <= u;i ++)if(up[i] < q[t]) break;int tmp = up[i];//记录原来的值,我们需要剪枝up[i] = q[t];dfs(max(u, i), d, t + 1);//恢复现场up[i] = tmp;int j;//这里我们要找的递减子序列,那么找的一定是所有递减子序列中最后一个数中,//大于加入的新数,//而且还要找递减子序列中大于新数的最小那个那个数,//这样才能让后面的数有更多的机会放入到递减子序列中//down默认是一个单剪序列for(j = 1;j <= d;j ++)if(down[j] > q[t]) break;int temp = down[j];down[j] = q[t];dfs(u, max(d, j), t + 1);//恢复现场down[j] = temp;
}int main()
{while(cin >> n && n){ans = 100;for(int i = 0;i < n;i ++)cin >> q[i];dfs(0, 0, 0);printf("%d\n", ans);}return 0;
}

在这里插入图片描述

三、最长公共上升子序列

题目链接
在这里插入图片描述
贴一下y总的题解

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 3010;
int n;
int f[N][N];
int a[N], b[N];int main()
{cin >> n;for(int i = 1;i <= n;i ++) cin >> a[i];for(int i = 1;i <= n;i ++) cin >> b[i];//我们以b[j]元素为研究对象//a[i]和b[j]是否能够匹配上for(int i = 1;i <= n;i ++){int rmax = 1;for(int j = 1;j <= n;j ++){f[i][j] = f[i - 1][j];if(a[i] == b[j]) f[i][j] = max(f[i][j], rmax);if(a[i] > b[j]) rmax = max(rmax, f[i - 1][j] + 1);}}int res = 0;for(int i = 1;i <= n;i ++) res = max(res, f[n][i]);cout << res;return 0;
}

y总课程板书图解
在这里插入图片描述

在这里插入图片描述

四、二分函数速写

在这里插入图片描述

基础课题解

五、最长上升子序列 II

题目链接
在这里插入图片描述

这个题有时间限制时间复杂度必须满足nlogn

#include <iostream>
#include <algorithm>using namespace std;const int N = 100010;int n;
int a[N];
int q[N];int main()
{scanf("%d", &n);for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);int len = 0;for (int i = 0; i < n; i ++ ){int l = 0, r = len;while (l < r){int mid = l + r + 1 >> 1;if (q[mid] < a[i]) l = mid;else r = mid - 1;}len = max(len, r + 1);q[r + 1] = a[i];}printf("%d\n", len);return 0;
}

http://www.ppmy.cn/news/1542384.html

相关文章

qt 滚动条 美化

qt QScrollBar 滚动条分为竖直与水平滚动条&#xff0c;两者设置上类似&#xff0c;但也有一些不同&#xff0c;下面主要讲述美化及注意事项。 一、竖直滚动条 竖直滚动条分为7个部分&#xff1a; sub-line、 up-arrow 、sub-page、 hanle、 add-line、 dow-arrow、 add-pag…

【Android】多渠道打包配置

目录 简介打包配置签名配置渠道配置配置打包出来的App名称正式包与测试包配置 打包方式开发工具打包命令行打包 优缺点 简介 多渠道打包 是指在打包一个 Android 应用时&#xff0c;一次编译生成多个 APK 文件&#xff0c;每个 APK 文件针对一个特定的渠道。不同的渠道可能代表…

从0到1学习node.js(npm)

文章目录 一、NPM的生产环境与开发环境二、全局安装三、npm安装指定版本的包四、删除包 五、用npm发布一个包六、修改和删除npm包1、修改2、删除 一、NPM的生产环境与开发环境 类型命令补充生产依赖npm i -S uniq-S 等效于 --save -S是默认选项npm i -save uniq包的信息保存在…

论文略读Fewer Truncations Improve Language Modeling

ICML 2024 1 背景 在传统LLM训练过程中&#xff0c;为了提高效率&#xff0c;通常会将多个输入文档拼接在一起&#xff0c;然后将这些拼接的文档分割成固定长度的序列。 ——>会造成一个重大问题——文档截断&#xff08;document truncation&#xff09;&#xff0c;损害…

qt 序列化和反序列化

序列化&#xff1a;QByteArray buffer; QBuffer bufferDevice(&buffer); bufferDevice.open(QIODevice::WriteOnly); QDataStream out(&bufferDevice); out.setVersion(QDataStream::Qt_5_13); 反序列化&#xff1a; void deserialize(const QByteArray &buffer) {…

【计算机网络 - 基础问题】每日 3 题(五十五)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

笔记整理—linux驱动开发部分(2)模块信息与编译

对于linux而言&#xff0c;.ko文件为驱动文件&#xff0c;在终端可以使用lsmod列出已经安装的模块&#xff0c;使用insmod xxx.ko安装所需要的模块&#xff0c;modinfo xxx.ko打印某个模块提供的信息&#xff0c;rmmod xxx卸载某个不需要的模块。 insmod与module_init宏。在源代…

PgSQL常用SQL语句

PgSQL常用SQL语句 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 PgSQL是一种开源的关系型数据库管理系统&#xff0c;它是PostgreSQL的一种实现。本文将介绍一些常用的PgSQL SQL语句&a…