蓝桥杯(4):python动态规划DF[1]

动态规划相当于正着想?dfs主要适用于位置的变化?

子问题!状态,状态转移方程

1 一维DP

1.1 定义

重叠子问题!转换成子问题 ,与记忆化搜索很像

1.2 例子

1.2.1 上楼梯

子问题到最终的问题只能跨一步:比如:4个台阶的话,可以从2或3走上来,但没有1!!!

1到4肯定要跨两步了

其实 就是斐波那契数列

#上楼梯
n = int(input())
dp = [0]*(n+1)
dp[1] = 1
dp[2] = 2
for i in range(3,n+1):dp[i] = dp[i-1] + dp[i-2]
print(dp[n])

1.3 步骤

1.4 例题

1.4.1 破损的楼梯

# 破损的楼梯
n,m = list(map(int,input().split()))
a = list(map(int,input().split()))
vis = [0]*(n+1)
for i in a:vis[i]=1
dp = [0]*(n+1)
dp[0]=1
dp[1] =1-vis[1]
for i in range(2,n+1):if vis[i]==1:continuedp[i] = dp[i-1]+dp[i-2]
print(dp[n])

1.4.2 安全序列

##安全序列
#输入
n,k = list(map(int,input().split()))
dp = [0]*(n+1)
dp[0] = 1
dp[1] = 2
mod = 10**9+7
for i in range(2,n+1):if i-k-1>0:#说明和这个位置相隔k的位置是存在的或许可以放置#dp[i-1]说明没有放置! dp[i-k-1]说明放置了#没有放置,则和前面的方案数一样;放置,则前间隔n个都不能放置,方案数为第(i-k-1)位置上的大小咯dp[i] = (dp[i-1]+dp[i-k-1])%modelse:dp[i] = (dp[i-1]+1)%mod
print(dp[n])

2 二维DP

2.1 定义

2.2 例题

2.2.1 数字三角形

用状态1写

##数字三角形
# 特点:第n行有n个数字
n = int(input())
a = [[0],]
dp = [[0]*(i+1) for i in range(n+1)]
for i in range(n):a.append([0] + list(map(int, input().split())))#用状态1写:(i,j)表示从(i,j)往下走的最大和
#输出的应该是dp[1][1]
for i in range(n,0,-1):for j in range(1,i+1):if i==n:dp[i][j]=a[i][j]else:dp[i][j] = max(dp[i+1][j],dp[i+1][j+1]) +a[i][j]
print(dp[1][1])# 5
# 7
# 3 8
# 8 1 0
# 2 7 4 4
# 4 5 2 6 5

用状态2写

##数字三角形
# 特点:第n行有n个数字
n = int(input())
a = [[0],]
dp = [[0]*(n+1) for i in range(n+1)]
for i in range(n):a.append([0] + list(map(int, input().split())))#(i,j)表示到达(i,j)的最大和
for i in range(1,n+1):for j in range(1,i+1):if i==1:dp[1][1] = a[1][1]else:dp[i][j] = max(dp[i-1][j-1],dp[i-1][j])+a[i][j]print(max(dp[n]))

2.2.2 摆花

#摆花
n,m = list(map(int,input().split()))
a = [0]+list(map(int,input().split()))
# 摆到第i个花的时候已经有j盆花了
# dp[i][j]
# 第i种花,摆0到i盆
# dp[i][j]= dp[i-1][j]+dp[i-1][j-1]+dp[i-1][j-2] +......+dp[i-1][j-i]
# 边界:dp[0][0] = 1 dp[0][1] =1 dp[0][j] = 0
# dp[1][1]=2
dp = [[1]+[0]*m for i in range(n+1)]for i in range(1,n+1):for j in range(1,m+1): #有几盆花for k in range(0,min(a[i],j)+1):dp[i][j] += dp[i-1][j-k]dp[i][j]%=10**6+7
print(dp[n][m])

2.2.3 选数异或

n,x = list(map(int,input().split()))
a = [0]+list(map(int,input().split()))
# 状态dp[i][j]表示前i个数字异或的值是j
# 状态转移: 当第i个数字选择的时候 dp[i][j] = dp[i-1][j^a[i]]
# 当第i个数字没选的时候 dp[i][j] = dp[i-1][j]
dp = [[0]*64 for i in range(n+1)]
dp[0][0] = 1
for i in range(1,n+1):for j in range(64):dp[i][j] = (dp[i-1][j]+dp[i-1][j^a[i]]) % 998244353
print(dp[n][x])

3 最长上升子序列

3.1 定义

3.1.1 子序列

状态是什么?

后面的数字必须比前面的大!!

比如现在拿到的时a[2](值为4),这时前面比4小的有1和3,对应的长度分别时1和2

就选2 在2的基础上再加1

3.2 例题

3.2.1 蓝桥勇士

n = int(input())
a = [0] + list(map(int,input().split()))
dp = [1]*(n+1)# i表示选择第i个数字
# j表示前面的数字
for i in range(1,n+1):for j in range(1,i):if a[j]<a[i]:dp[i] = max(dp[j]+1 ,dp[i])print(max(dp))

注意边界全是1!!!!!!!!刚开始以自己结尾一定选自己,方案数为1!!

3.2.2 合唱队形

# 最高的中间旁边依次降低
# 假设最高的站在第i个位置 i前面是上升序列  i后面是下降序列
n = int(input())
t = [0]+list(map(int,input().split()))
dp1 = [1]*(n+1) #存储最大上升子序列
dp2 = [1]*(n+1) #存储最大下降子序列
for i in range(1,n+1):for j in range(1,i):if t[j]<t[i]:dp1[i] = max(dp1[j]+1,dp1[i])
# print(dp1)
for i in range(n,0,-1):for j in range(i+1,n+1):if t[i]>t[j]:dp2[i] = max(dp2[j]+1,dp2[i])
# print(dp2)
ans = max([dp1[i]+dp2[i]-1 for i in range(1,n+1)])
print(n-ans)

4 最长公共子序列

4.1 定义

对于两个数组而言的

如果dp[i][j]对应的a[i]和b[j]是相等的说明 子序列的长度可以加1,在谁的基础上加1呢,左上角的就都可以!!!!【观察这个矩阵不看边界,可以知道对角线上的元素是一样的】加1肯定是在上一个对角线上咯!!!

如果对应的值不相等 说明这时的值还是上一条对角线对应的值,所以往上或左找 就是他!

怎么找出具体的公共子序列:

可以向上走或者想左走:说明上一条对角线的数和自己相同,没有发生状态转移,则回到这个位置,试图找到发生转移的点

不可以走的时候:说明发生的状态转移,转移一定发生在正对角线上!!!

4.2 例题

def output(a):n = len(a)for i in range(0,n):print(" ".join(map(str,a[i][0:])))n,m = list(map(int,input().split()))
a = [0]+list(map(int,input().split()))
b = [0]+list(map(int,input().split()))
dp = [[0]*(m+1) for i in range(n+1)]#状态
for i in range(1,n+1):for j in range(1,m+1):if a[i] == b[j]:dp[i][j] = dp[i-1][j-1] +1else:dp[i][j] = max([dp[i-1][j],dp[i][j-1]])
# output(dp)
print(dp[n][m])

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rredis缓存常见面试题

文章目录 1.什么是缓存穿透&#xff0c;怎么解决2.什么是缓存击穿&#xff0c;怎么解决3.什么是缓存雪崩&#xff0c;怎么解决4.双写一致性问题5.redisson添加的排他锁是如何保证读写、读读互斥的6.为什么不使用延迟双删7.redis做为缓存&#xff0c;数据的持久化是怎么做的8.re…

LInux脚本学习

1.注释 #单行注释 以 # 字符开头就是单行注释 当然第一行除外&#xff0c;比较特殊 2.多行注释 3.Shell文件的作用 Shell文件就是linux命令集 4.sh脚本的执行方式 bash xxx.sh 5.新建的文件会没有执行权限 #为文件赋予执行权限 chmod ux xxx.sh 6.编写规范 #!/bin/bash #…

Discuz! X3.5苗木_苗木网_苗木价格_苗木求购信息_苗木批发网模板utf-8

适合做苗木行业平台苗木网站、苗木信息网,提供苗木报价、各地苗木求购信息、绿化苗木采购招标、苗木基地展示、苗木百科知识、花木交易及苗木资讯、各地苗木信息网络行情。解压上传到template目录下&#xff0c;后台安装即可&#xff0c;包含PC手机端模板 下载地址&#xff1a;…

容器的底层技术:CGroup和NameSpace

无论是容器&#xff0c;还是虚拟机&#xff0c;都依赖于内核中的技术&#xff0c;虚拟机依赖的是 KVM&#xff0c;容器依赖的是 namespace 和 cgroup 对进程进行隔离和资源限制。 容器实现封闭的环境主要要靠两种技术&#xff0c;一种是看起来是隔离的技术&#xff0c;称为nam…

自然语言处理NLP概述

大家好&#xff0c;自然语言处理(NLP)是计算机科学领域与人工智能领域中的一个重要方向&#xff0c;其研究能实现人与 计算机之间用自然语言进行有效通信的各种理论和方法。本文将从自然语言处理的本质、原理和应用三个方面&#xff0c;对其进行概述。 一、NLP的本质 NLP是一…

定时器-间歇函数

1.开启定时器 setInterval(function (){console.log(一秒执行一次)},1000) function fn(){console.log(一秒执行一次) } setInterval(fn,1000) //调用有名的函数&#xff0c;只写函数名 1.函数名字不需要加小括号 2.定时器返回是一个id数字 每个定时器的序号是不一样的 2.关…

Codigger Desktop:开发者的利器,每个人的好帮手(二)

昨日&#xff0c;我们为大家揭开了Codigger Desktop开发者利器的三种特性&#xff0c;展现了其独特的亮点。今日&#xff0c;我们将继续为大家呈现另外三项引人注目的特性&#xff0c;以展现这款工具的全面实力。 一、AI辅助&#xff1a;智能识别Module&#xff0c;环境配置一步…

【JAVASE】学习类与对象的创建和实例化

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 目标&#xff1a; 1. 掌握类的定义方式以及对象的实例化 2. …

鸿蒙OS开发实例:【应用事件打点】

简介 传统的日志系统里汇聚了整个设备上所有程序运行的过程流水日志&#xff0c;难以识别其中的关键信息。因此&#xff0c;应用开发者需要一种数据打点机制&#xff0c;用来评估如访问数、日活、用户操作习惯以及影响用户使用的关键因素等关键信息。 HiAppEvent是在系统层面…

Day18-【Java SE进阶】多线程

一、线程 1. 什么是线程? 线程(Thread)是一个程序内部的一条执行流程。程序中如果只有一条执行流程&#xff0c;那这个程序就是单线程的程序。 2. 多线程 多线程是指从软硬件上实现的多条执行流程的技术(多条线程由CPU负责调度执行) 3. 如何在程序中创建出多条线程? Ja…

MyBatis动态SQL--if 标签

mybatis动态sql对我们来说是非常常见的&#xff0c;比如在下面这样一个场景中&#xff0c; 我们需要多条件查询&#xff0c;但是查询的条件又不是固定的&#xff0c;是可以动态改变的&#xff0c;那我们就需要用到动态sql去完成。 动态SQL之 if 标签 接下来我们介绍第一个动态…

【fastadmin】脚本模式下,日志钩子函数执行出现死循环,导致内存溢出奔溃

问题出现原因是想对项目中error级别的日志&#xff0c;接入钉钉告警&#xff0c;方便查看 于是使用钩子方法&#xff0c;日志写入完成后&#xff0c;自动调用自定义的告警方法中 1、在application/tags.php 中添加log_write_done > [app\\common\\behavior\\Common, ],2、在…