算法自学__线性动态规划

例1 P1020 [NOIP1999 普及组] 导弹拦截

题目描述

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

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

输入格式

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

输出格式

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

样例 #1

样例输入 #1

389 207 155 300 299 170 158 65

样例输出 #1

6
2

提示

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

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

思路

这道题目实质上就是考察最长不上升子序列最长上升子序列的求法,以前者为例。

定义tail1[i],表示:长度i的不上升子序列的最后一个元素的值。显然,tail1[]数组是单调不升的。定义cnt1表示当前最长不上升子序列的长度。我们从头至尾遍历输入的每一个元素,如果当前元素:

  • ≤ \leq tail1[cnt1],说明当前元素可以直接添加到目前的最长不上升子序列的末尾,形成一个更长的子序列。
  • > > > tail1[cnt2],我们二分查找到tail1[]数组中第一个小于当前元素的值tail1[i],并将其修改为当前元素。首先,这样做是可行的,因为tail1[i-1] 一定 ≥ \ge 当前元素,所以将当前元素接在一个长度为i-1的不上升子序列的结尾,可以形成一个长度为i的不上升子序列,符合tail1[]数组的定义。其次,这样做是合理的,因为在一个不上升子序列中,位于前面的元素越大,这个子序列便可能越长。

遍历输入的所有元素后,cnt1的值即为最长不上升子序列的长度。

代码

#include<bits/stdc++.h>
#define maxn 100005
using namespace std;

int a[maxn];
int n = 0;
int tail1[maxn];
int tail2[maxn];
int cnt1=0, cnt2=0;

int main(){
	int temp;
	while(cin>>temp){
		n++;
		a[n] = temp;
	}
	tail1[0] = 0x7f7f7f7f;
	tail2[0] = -1;
	for(int i=1;i<=n;i++){
		if(a[i]<=tail1[cnt1]){
			cnt1++;
			tail1[cnt1] = a[i];
		}
		else{
			int L=1, R=cnt1, pos=0;
			while(L<=R){
				int mid = (L+R)>>1;
				if(tail1[mid]<a[i]){
					pos = mid;
					R = mid-1;
				}
				else{
					L = mid+1;
				}
			}	
			tail1[pos] = a[i];
		}
	}
	for(int i=1;i<=n;i++){
		if(a[i]>tail2[cnt2]){
			cnt2++;
			tail2[cnt2] = a[i];
		}
		else if(a[i]==tail2[cnt2]){
			continue;
		}
		else{
			int L=1, R=cnt2, pos=0;
			while(L<=R){
				int mid = (L+R)>>1;
				if(tail2[mid]>=a[i]){
					pos = mid;
					R = mid-1;
				}
				else{
					L = mid+1;
				}
			}
			tail2[pos] = a[i];
		}
	}
	cout<<cnt1<<'\n'<<cnt2;
	return 0;
}

例2 P2679 [NOIP2015 提高组] 子串

题目描述

有两个仅包含小写英文字母的字符串 A A A B B B

现在要从字符串 A A A 中取出 k k k 个互不重叠的非空子串,然后把这 k k k 个子串按照其在字符串 A A A 中出现的顺序依次连接起来得到一个新的字符串。请问有多少种方案可以使得这个新串与字符串 B B B 相等?

注意:子串取出的位置不同也认为是不同的方案。

输入格式

第一行是三个正整数 n , m , k n,m,k n,m,k,分别表示字符串 A A A 的长度,字符串 B B B 的长度,以及问题描述中所提到的 k k k,每两个整数之间用一个空格隔开。

第二行包含一个长度为 n n n 的字符串,表示字符串 A A A

第三行包含一个长度为 m m m 的字符串,表示字符串 B B B

输出格式

一个整数,表示所求方案数。

由于答案可能很大,所以这里要求输出答案对 1000000007 1000000007 1000000007 取模的结果。

样例 #1

样例输入 #1

6 3 1 
aabaab 
aab

样例输出 #1

2

提示

对于第 1 组数据: 1 ≤ n ≤ 500 , 1 ≤ m ≤ 50 , k = 1 1≤n≤500,1≤m≤50,k=1 1n500,1m50,k=1;
对于第 2 组至第 3 组数据: 1 ≤ n ≤ 500 , 1 ≤ m ≤ 50 , k = 2 1≤n≤500,1≤m≤50,k=2 1n500,1m50,k=2;
对于第 4 组至第 5 组数据: 1 ≤ n ≤ 500 , 1 ≤ m ≤ 50 , k = m 1≤n≤500,1≤m≤50,k=m 1n500,1m50,k=m;
对于第 1 组至第 7 组数据: 1 ≤ n ≤ 500 , 1 ≤ m ≤ 50 , 1 ≤ k ≤ m 1≤n≤500,1≤m≤50,1≤k≤m 1n500,1m50,1km;
对于第 1 组至第 9 组数据: 1 ≤ n ≤ 1000 , 1 ≤ m ≤ 100 , 1 ≤ k ≤ m 1≤n≤1000,1≤m≤100,1≤k≤m 1n1000,1m100,1km;
对于所有 10 组数据: 1 ≤ n ≤ 1000 , 1 ≤ m ≤ 200 , 1 ≤ k ≤ m 1≤n≤1000,1≤m≤200,1≤k≤m 1n1000,1m200,1km

思路

定义状态f[i][j][k]表示:在字符串a的前i个字符中任意选取k个子串,且必须选择a[i],能拼出字符串b的前j个字符构成的子串的方案数

定义状态g[i][j][k]表示:在字符串a的前i个字符中任意选取k个子串,a[i]可选可不选,能拼出字符串b的前j个字符构成的子串的方案数

状态转移方程一:
f [ i ] [ j ] [ k ] = { f [ i − 1 ] [ j − 1 ] [ k ] + g [ i − 1 ] [ j − 1 ] [ k − 1 ] , a [ i ] = = b [ j ] 0 , a [ i ]   ! = b [ j ] f[i][j][k] = \begin{cases} f[i-1][j-1][k] + g[i-1][j-1][k-1], &a[i]==b[j]\\ 0, &a[i]\ !=b[j] \end{cases} f[i][j][k]={f[i1][j1][k]+g[i1][j1][k1],0,a[i]==b[j]a[i] !=b[j]
解释:当a[i]b[i]不相等时,f[i][j][k]显然为0。当a[i]b[i]相等时,a[i]要么和别的字符共同构成一个子串,要么自己单独构成一个子串。和别的字符共同构成一个子串的情形,对应f[i-1][j-1][k],即a[i]添加到了a[i-1]所在子串的末尾;单独构成一个子串的情形,对应g[i-1][j-1][k-1],即前面选出k-1个子串,构成b[1]~b[j-1]的部分。

状态转移方程二:
g [ i ] [ j ] [ k ] = f [ i ] [ j ] [ k ] + g [ i − 1 ] [ j ] [ k ] g[i][j][k] = f[i][j][k] + g[i-1][j][k] g[i][j][k]=f[i][j][k]+g[i1][j][k]
解释:根据g[i][j][k]的定义,a[i]要么选,要么不选。选的情形,对应f[i][j][k];不选的情形,对应g[i-1][j][k]

代码

#include<bits/stdc++.h>

using namespace std;

const int maxn = 1005;
const int maxm = 205;
const int p = 1000000007;

int f[2][maxm][maxm];
int g[2][maxm][maxm];
int cnt = 0;
int n, m, K;
char a[maxn], b[maxm];

int main(){
	cin>>n>>m>>K;
	//让字符串从下标1开始
	cin>>a+1>>b+1;
	//保证(a[i]==b[j])为真,且j为1、k为1时,f[cnt][j][k]为1
	g[0][0][0] = g[1][0][0] = 1;
	//滚掉i
	for(int i=1;i<=n;i++){
		for(int j=1;j<=min(m, i);j++){
			for(int k=1;k<=K;k++){
				if(a[i]==b[j]){
					f[cnt][j][k] = (f[cnt^1][j-1][k]+g[cnt^1][j-1][k-1]) % p;
				}
				else{
					f[cnt][j][k] = 0;
				}
				g[cnt][j][k] = (g[cnt^1][j][k]+f[cnt][j][k]) % p;
			}
		}
		cnt = cnt^1;
	}
	cout<<g[cnt^1][m][K];
	return 0;
}

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

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

相关文章

Word控件Spire.Doc 【页眉页脚】教程(10): 锁定标题以防止在 C# 中编辑 word 文档

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

【电商干货】旺旺满意度考核你达标了吗?

现在很多买家在进行淘宝网购之前都会通过旺旺找客服咨询一些问题&#xff0c;而在咨询完后大家还可以对店铺客服进行满意度评分。不过有时候大家可能会点错了这个满意度&#xff0c;然后就想要去进行修改。那么&#xff0c;淘宝旺旺满意度可以修改吗?满意度考核又是什么?又该…

Autosar COM Stack系列介绍01_一文看懂各层PDU

本文框架1. 概述1.1 缩写2. OSI模型在Autosar中应用3. 各层PDU介绍3.1 L-PDU3.2 N-PDU3.2.1 N_AI3.2.2 N_PCI3.3 I-PDU1. 概述 在学习Autosar通信栈时中会遇到关于PDU的各种缩写&#xff0c;例如&#xff0c;L-PDU&#xff0c;N-PDU&#xff0c;I-PDU还有SDU等&#xff0c;它们…

shiro漏洞复现及其攻击流量分析

前言 最近面试时经常被问到&#xff0c;每次说的都不太完美&#xff0c;现在再来复现一边。 shiro介绍 Apache Shiro是一个开源安全框架&#xff0c;提供身份验证、授权、密码学和会话管理。 CVE-2016-4437 利用vulhub搭建的靶场。 在Apache Shiro < 1.2.4版本中存在反…

有哪些 python 的在线练习题或编程挑战的网站?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 学习编程语言&#xff0c;练习必不可少&#xff0c;在练习和做题的过程中能够查漏补缺&#xff0c;清楚自己在理论学习过程中的不足和薄弱点&#xff0c;加深对于Python的理解和认识。 请注意&#x…

4.6---Spring框架之Spring的AOP理解(复习版本)

AOP&#xff0c;称为面向切面&#xff0c;作为面向对象的一种补充&#xff1b; 用于将那些与业务无关&#xff0c;但却对多个对象产生影响的公共行为和逻辑&#xff0c;抽取并封装为一个可重用的模块&#xff0c;这个模块被命名为“切面”&#xff08;Aspect&#xff09;&…

一致性哈希的简单认识

简介 在分布式集群中&#xff0c;对机器的添加、删除或者是机器故障后自动脱离集群等操作是分布式集群管理最基本的功能。如果采用的是常见的取模哈希算法&#xff0c;当有机器添加、删除之后&#xff0c;需要对数据做迁移&#xff0c;非常麻烦。 而一致性哈希利用哈希环的概…

蓝牙耳机品牌哪个音质好佩戴舒适性?2023年蓝牙耳机盘点

现如今&#xff0c;能够便利日常生活的产品越来越受到人们的欢迎&#xff0c; 一部手机、一副耳机似乎已然成为人们出行的标志之一。 但很多人在戴耳机时通常会忘记时间&#xff0c;直到耳朵有痛感了才摘下。 那么就有了一个疑问&#xff1a;哪种耳机戴的最舒服&#xff1f;…

今年晋升本没抱希望,已有绩效更好的同事将参加晋升,leader却临时让我也去答辩,怀疑自己被拉去陪跑,该怎么办?...

被临时通知参加晋升答辩&#xff0c;这是好事吗&#xff1f;一位网友问&#xff1a;本来今年晋升没报希望&#xff0c;但leader昨天突然让他临时准备下下周的晋升汇报&#xff0c;说看他今年工作非常努力&#xff0c;很认可他的态度&#xff0c;所以额外重点提报了他参与晋升汇…

Spring依赖注入详解

1.set注入 启动容器后看看到底能不能拿到teacherService的值。可以看到拿到了值。我们具体来分析怎么注入的 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 发现pvs里面有一个我们自己set的值 直接进行属性赋值。 org.springf…

Linux中滴计划任务

计划任务计划任务计划任务分类at命令load averagecrontab命令配置文件通常包含三个部分cron服务配置文件cron服务的日志文件时间数值的特殊表示方法应用实例案例anacron服务计划任务 计划任务&#xff08;Cron Job&#xff09;是指在预定的时间自动执行一些指定的任务或脚本。…

普通人怎么用ChatGPT-ChatGPT中文版网页

去哪下载ChatGPT ChatGPT是一种自然语言处理算法&#xff0c;其模型是由OpenAI团队开发的。如果你需要使用ChatGPT模型进行自然语言处理任务&#xff0c;你可以从OpenAI官方网站获取模型和相关工具。 具体来说&#xff0c;你可以访问OpenAI的网站&#xff0c;然后在“Researc…

CarSim仿真快速入门(二十四)-CarSimSimulink联合仿真中的输入和输出IO接口

导入和导出数组用于Simulink以外的外部仿真工具。同样的设置也用于LabVIEW、ASCET、FMI/FMU以及可能用MATLAB、Python和其他语言编写的自定义程序。 在所有这些情况下,I/O通道。导入和I/O通道。输出屏幕用于配置VS数学模型以满足外部仿真工具的通信要求。 I/O 通道:输出 输…

元宇宙与网络安全

元宇宙是一种虚拟现实空间&#xff0c;用户可以在计算机生成的环境中进行互动。元宇宙的应用范围很广&#xff0c;比如房地产&#xff0c;医疗&#xff0c;教育&#xff0c;军事&#xff0c;游戏等等。它提供了更具沉浸感的体验&#xff0c;更好地现实生活整合&#xff0c;以及…

three.js实现3d球体树状结构布局——树状结构的实现

目录系列文章安装依赖基本分析实体类场景相机渲染器辅助线环境光点光源球形几何体球形几何体的材质线几何体线几何体的材质物体文本轨道控制实现效果实现源码参考文档系列文章 three.js实现3d球体树状结构布局——添加入场、出场、点击放大等动画 安装依赖 npm i three three…

【软件设计师07】程序设计语言与语言处理程序基础

程序设计语言与语言处理程序基础 编译与解释、文法、正规式、有限自动机、表达式、传值与传址、多中程序语言特点 1. 编译过程 2. 文法定义 (逐渐降低考察比例&#xff0c;很少考察) 概念 文法类型 语法推导树 有限自动机与正规式&#xff08;重点&#xff09; 常见问题&a…

UVM response_handler和get_response机制

很多UVM用户平时更多的使用get_response()方式去获得uvm_driver的response&#xff0c;但get_response有些缺点&#xff1a;由于 get_response() 是一种阻塞方法&#xff0c;它会阻塞直到收到来自 UVM 驱动程序 (put_response()) 的响应。因此&#xff0c;如果我们使用 get_res…

Vue3加载中(Spin)

Vue2加载中&#xff08;Spin&#xff09; 可自定义设置以下属性&#xff1a; 是否为加载中状态&#xff08;spinning&#xff09;&#xff0c;类型&#xff1a;boolean&#xff0c;默认 true 组件大小&#xff08;size&#xff09;&#xff0c;类型&#xff1a;string&#x…

国内ChatGPt研发-中国chatGPT

人工智能软件chatGPT Chat GPT是一种自然语言处理算法&#xff0c;采用了深度学习技术&#xff0c;用于实现文本生成和自然语言处理任务。它可以实现自然而然的人机交互&#xff0c;在自然语言生成和问答领域应用广泛。 值得注意的是&#xff0c;Chat GPT本身并不是一款具体的…

VB execl函数 word文档 KBS

文章目录1. VB1.1 程序结构1.2 基本语法1.3 数据类型1.4 变量1.4.1 变量声明1.5 常量和枚举1.5.1 声明常量1.5.2 声明枚举1.6 数据库2. KBS3. execl函数2.1 分割页面4. word文档4.1 如何分节4.2 如何删除节4.3 页脚如何自增4.4 多页显示1. VB 1.1 程序结构 命名空间声明一个类…
最新文章