【算法】动态规划专题① ——线性DP python

目录

  • 引入
  • 简单实现
  • 稍加变形
  • 举一反三
  • 实战演练
  • 总结


引入


楼梯有个台阶,每次可以一步上1阶或2阶。一共有多少种不同的上楼方法?

怎么去思考?
假设就只有1个台阶,走法只有:1
只有2台阶: 1+1,2
只有3台阶: 1+2, 1+1+1 ,2+1
只有4台阶: 1+1+2 ,2+2 , 1+2+1 ,1+1+1+1,2+1+1
不难观察到
3台阶的走法可以表示为1台阶的走法再+2,2台阶的走法+1
4台阶的走法可以表示为2台阶的走法再+2,3台阶的走法+1
自然递推出:
n台阶的走法可以表示为n-2台阶的走法再+2,n-1台阶的走法+1


解决步骤:
1.定义状态:
设dp[n]表示到达第n级台阶的不同方法总数。
2.状态转移方程:
因为每次只能走1步或2步,所以到达第n级台阶的方法数等于到达第(n-1)级台阶的方法数加上到达第(n-2)级台阶的方法数。
dp[n]=dp[n-1]+dp[n-2]
3.初始化:
当n=0时,没有台阶,认为有一种方法(什么都不做),因此dp[0]=1。
当n=1时,只有一种方法,即直接走上第一级台阶,所以dp[1]=1。
4.计算顺序:从低到高依次计算每一级台阶的方法数直到n。



简单实现


跳台阶 https://www.acwing.com/problem/content/823/

一个楼梯共有 n n n 级台阶,每次可以走一级或者两级,问从第 0 0 0 级台阶走到第 n n n 级台阶一共有多少种方案。

输入格式

共一行,包含一个整数 n n n

输出格式

共一行,包含一个整数,表示方案数。

数据范围

1 ≤ N ≤ 15 1\leq N\leq15 1N15

输入样例:

5

输出样例:

8

代码如下(示例):
n = int(input())
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 1
for i in range(2, n + 1):dp[i] = dp[i - 1] + dp[i - 2]
print(dp[n])


稍加变形


哎,就是玩 给你几个楼梯弄坏

破损的楼梯 https://www.lanqiao.cn/problems/3367/learning/?page=1&first_category_id=1&problem_id=3367

在这里插入图片描述

思路:

用vis数组标记不能走的台阶即可


题解code:

mod = 1000000007
n, m = map(int, input().split())
a = list(map(int, input().split()))
dp = [0] * (n + 1)
dp[0] = 1
vis = [0] * (n + 1)
for i in a:vis[i] = 1
for i in range(1, n + 1):if vis[i] == 0:dp[i] = (dp[i - 1] + dp[i - 2]) % mod
print(dp[n])


举一反三


每次可以走一级或者两级或者三级,一共有多少种方案呢?
测试链接 https://www.acwing.com/problem/content/3646/


每次可以向上迈 1∼K 级台阶,答案又是多少呢?
在这里我们给出1-k级台阶的解法


台阶问题 https://www.luogu.com.cn/problem/P1192

题目描述

N N N 级台阶,你一开始在底部,每次可以向上迈 1 ∼ K 1\sim K 1K 级台阶,问到达第 N N N 级台阶有多少种不同方式。

输入格式

两个正整数 N , K N,K N,K

输出格式

一个正整数 a n s ( m o d 100003 ) ans\pmod{100003} ans(mod100003),为到达第 N N N 级台阶的不同方式数。

样例输入

5 2

样例输出

8

提示

  • 对于 20 % 20\% 20% 的数据, 1 ≤ N ≤ 10 1\leq N\leq10 1N10 1 ≤ K ≤ 3 1\leq K\leq3 1K3
  • 对于 40 % 40\% 40% 的数据, 1 ≤ N ≤ 1000 1\leq N\leq1000 1N1000
  • 对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 100000 1\leq N\leq100000 1N100000 1 ≤ K ≤ 100 1\leq K\leq100 1K100

思路分析:

结合上面所学,不难得出:
dp[ i i i] = dp[ i i i - 1] + dp[ i i i - 2] + ······ +dp[ i i i - k k k]
当然,这是 i ≥ k i\geq k ik的情况
对于 i < k i< k i<k:
dp[ i i i] = dp[ i i i - 1] + dp[ i i i - 2] + ······ +dp[0]

题解code

mod = 100003n, k = map(int, input().split())
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 1
for i in range(2, n + 1):res = 0for j in range(min(i, k) + 1):res += dp[i - j]dp[i] = res % mod
print(dp[n])


结合前缀和能更快得出答案
什么?还不会前缀和?
点此跳转 超细致讲解


code:

mod = 100003
n, k = map(int, input().split())
dp = [0] * (n + 1)
dp[0] = 1
pre_sum = [0] * (n + 2)
pre_sum[1] = 1
for i in range(1, n + 1):if i <= k:dp[i] = pre_sum[i] % modelse:dp[i] = (pre_sum[i] - pre_sum[i - k]) % modpre_sum[i + 1] = (pre_sum[i] + dp[i]) % mod
print(dp[n])



实战演练


安全序列 https://www.lanqiao.cn/problems/3423/learning/?page=1&first_category_id=1&problem_id=3423

在这里插入图片描述

思路分析:

只有一个空位,那么只有 {0},{1}两种放法
两个空位,那么在上面的基础上放0或者隔k个0放1
{0,0},{1,0},{0,1}
三个空位,直接放0,或者隔k个0放1
{0,0,0} ,{1,0,0},{0,1,0}, {0,0,1}
四个空位,继续递推
{0,0,0,0} {1,0,0,0} {0,1,0,0} {0,0,1,0} {0,0,0,1} {1,0,0,1}
得到递推公式:
写出状态转移方程:
dp[ i i i] = dp[ i i i-1](后面直接放0)+ dp[ i i i- k k k-1](隔k个0后放1)


题解code:

mod = 1000000007
n, k = map(int, input().split())
dp = [0] * (n + 1)
dp[0] = 1
for i in range(1, n + 1):if i - k - 1 >= 0:dp[i] = (dp[i - k - 1] + dp[i - 1]) % modelse:dp[i] = (1 + dp[i - 1]) % mod
print(dp[n])


总结


线性动态规划(Linear Dynamic Programming, 简称线性DP)是一种动态规划的类型,它主要处理具有线性结构的问题。
在这种问题中,通常会有一个或多个序列作为输入,而解决这些问题的目标是找到满足某些条件的最优解。
线性DP问题的特点是可以将问题分解为若干个子问题,每个子问题仅涉及原问题的一个连续子序列,并且这些子问题之间存在重叠和递推关系。

本篇博客从台阶问题入手,逐步复杂化,帮助更好地理解一维线性DP


END
如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢

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

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

相关文章

C++11(中)

新增默认成员函数 C11之前&#xff0c;默认成员函数有六个&#xff0c;构造函数&#xff0c;析构函数&#xff0c;拷贝构造&#xff0c;拷贝赋值重载&#xff0c;取地址重载&#xff0c;const 取地址重载。 C11增加了 移动构造 和 移动赋值重载 如果类没有实现移动构造&…

强化学习笔记——4策略迭代、值迭代、TD算法

基于策略迭代的贝尔曼方程和基于值迭代的贝尔曼方程&#xff0c;关系还是不太理解 首先梳理一下&#xff1a; 通过贝尔曼方程将强化学习转化为值迭代和策略迭代两种问题 求解上述两种贝尔曼方程有三种方法&#xff1a;DP&#xff08;有模型&#xff09;&#xff0c;MC&#xff…

计算机网络 笔记 网络层 3

IPv6 IPv6 是互联网协议第 6 版&#xff08;Internet Protocol Version 6&#xff09;的缩写&#xff0c;它是下一代互联网协议&#xff0c;旨在解决 IPv4 面临的一些问题&#xff0c;以下是关于 IPv6 的详细介绍&#xff1a; 产生背景&#xff1a; 随着互联网的迅速发展&…

【搜索回溯算法篇】:拓宽算法视野--BFS如何解决拓扑排序问题

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;搜索回溯算法篇–CSDN博客 文章目录 一.广度优先搜索&#xff08;BFS&#xff09;解决拓扑排…

23.Word:小王-制作公司战略规划文档❗【5】

目录 NO1.2.3.4 NO5.6​ NO7.8.9​ NO10.11​ NO12​ NO13.14 NO1.2.3.4 布局→页面设置对话框→纸张&#xff1a;纸张大小&#xff1a;宽度/高度→页边距&#xff1a;上下左右→版式&#xff1a;页眉页脚→文档网格&#xff1a;勾选只指定行网格✔→ 每页&#xff1a;…

视频脚本生成器(基于openai API和streamlit)

utils.py&#xff1a; # 所有和ai交互的代码放进utils.py里&#xff08;utils 通常是 “utilities” 的缩写&#xff0c;意为 “实用工具” 或 “实用函数”&#xff09;from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from lan…

Android --- CameraX讲解

预备知识 surface surfaceView SurfaceHolder surface 是什么&#xff1f; 一句话来说&#xff1a; surface是一块用于填充图像数据的内存。 surfaceView 是什么&#xff1f; 它是一个显示surface 的View。 在app中仍在 ViewHierachy 中&#xff0c;但在wms 中可以理解为…

Longformer:处理长文档的Transformer模型

Longformer&#xff1a;处理长文档的Transformer模型 摘要 基于Transformer的模型由于自注意力操作的二次复杂度&#xff0c;无法处理长序列。为了解决这一限制&#xff0c;我们引入了Longformer&#xff0c;其注意力机制与序列长度呈线性关系&#xff0c;使其能够轻松处理数…

python学opencv|读取图像(五十二)使用cv.matchTemplate()函数实现最佳图像匹配

【1】引言 前序学习了图像的常规读取和基本按位操作技巧&#xff0c;相关文章包括且不限于&#xff1a; python学opencv|读取图像-CSDN博客 python学opencv|读取图像&#xff08;四十九&#xff09;原理探究&#xff1a;使用cv2.bitwise()系列函数实现图像按位运算-CSDN博客…

MySQL为什么默认引擎是InnoDB ?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL为什么默认引擎是InnoDB &#xff1f;】面试题。希望对大家有帮助&#xff1b; MySQL为什么默认引擎是InnoDB &#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL 默认引擎是 InnoDB&#xff0c;主要…

蓝桥杯真题k倍区间

题目如下 代码解析&#xff1a; 成功AC

python项目之requirements.txt文件

Python项目中可以包含一个 requirements.txt 文件&#xff0c;用于记录所有依赖包及其精确的版本号用以新环境部署。 当我们开发新项目的时候&#xff0c;会用virtualenv创建很多python独立环境&#xff0c;这时候就会出现在不同环境下安装相同的模块的情况&#xff0c;这时候…

算法题(53):对称二叉树

审题&#xff1a; 需要我们判断二叉树是否满足对称结构&#xff0c;并返回判断结果 思路&#xff1a; 方法一&#xff1a;递归 其实是否对称分成两部分判断 第一部分&#xff1a;根节点是否相等 第二部分&#xff1a;根节点一的左子树和根节点二的右子树是否相等&#xff0c;根…

使用 cmake

使用前注意 : CMake是一种跨平台的构建系统&#xff0c;它用于管理软件构建过程&#xff0c;尤其适合多语言、多配置的项目。CMake不直接构建软件&#xff0c;而是生成特定构建工具&#xff08;如Makefile或Visual Studio项目&#xff09;所需的配置文件。 如果仅仅使用 qt 编…

AI软件外包需要注意什么 外包开发AI软件的关键因素是什么 如何选择AI外包开发语言

1. 定义目标与需求 首先&#xff0c;要明确你希望AI智能体做什么。是自动化任务、数据分析、自然语言处理&#xff0c;还是其他功能&#xff1f;明确目标可以帮助你选择合适的技术和方法。 2. 选择开发平台与工具 开发AI智能体的软件时&#xff0c;你需要选择适合的编程语言、…

学习数据结构(5)单向链表的实现

&#xff08;1&#xff09;头部插入 &#xff08;2&#xff09;尾部删除 &#xff08;3&#xff09;头部删除 &#xff08;4&#xff09;查找 &#xff08;5&#xff09;在指定位置之前插入节点 &#xff08;6&#xff09;在指定位置之后插入节点 &#xff08;7&#xff09;删除…

深入理解MySQL 的 索引

索引是一种用来快速检索数据的一种结构, 索引使用的好不好关系到对应的数据库性能方面, 这篇文章我们就来详细的介绍一下数据库的索引。 1. 页面的大小: B 树索引是一种 Key-Value 结构&#xff0c;通过 Key 可以快速查找到对应的 Value。B 树索引由根页面&#xff08;Root&am…

Vue-cli 脚手架搭建

安装node.js 官网下载node.js安装包&#xff0c;地址&#xff1a;Node.js — Download Node.js 先在node.js即将要安装的路径下创建两个文件夹&#xff1a;node_cache&#xff08;缓存&#xff09;、node_global&#xff08;全局&#xff09; 点击安装包&#xf…

深度解析 DeepSeek R1:强化学习与知识蒸馏的协同力量

DeepSeek-R1 的问世&#xff0c;无疑在 AI 领域激起了千层浪。自发布仅一周&#xff0c;它便凭借卓越的性能和创新的技术&#xff0c;成为 AI 社区热议的焦点&#xff0c;代表着人工智能在推理和理解能力上的重大飞跃。今天我们一起深度解析一下DeepSeek-R1 一、强大基石&…

openssl 生成证书 windows导入证书

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…