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

news2025/4/17 19:26:21

目录

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


引入


楼梯有个台阶,每次可以一步上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 = 100003

n, k = map(int, input().split())
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 1
for i in range(2, n + 1):
    res = 0
    for 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] % mod
    else:
        dp[i] = (pre_sum[i] - pre_sum[i - k]) % mod
    pre_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]) % mod
    else:
        dp[i] = (1 + dp[i - 1]) % mod
print(dp[n])


总结


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

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


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

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

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

相关文章

知识管理平台在数字经济时代推动企业智慧决策与知识赋能的路径分析

内容概要 在数字经济时代&#xff0c;知识管理平台被视为企业智慧决策与知识赋能的关键工具。其核心作用在于通过高效地整合、存储和分发企业内部的知识资源&#xff0c;促进信息的透明化与便捷化&#xff0c;使得决策者能够在瞬息万变的市场环境中迅速获取所需信息。这不仅提…

LabVIEW微位移平台位移控制系统

本文介绍了基于LabVIEW的微位移平台位移控制系统的研究。通过设计一个闭环控制系统&#xff0c;针对微位移平台的通信驱动问题进行了解决&#xff0c;并提出了一种LabVIEW的应用方案&#xff0c;用于监控和控制微位移平台的位移&#xff0c;从而提高系统的精度和稳定性。 项目背…

java求职学习day23

MySQL 单表 & 约束 & 事务 1. DQL操作单表 1.1 创建数据库,复制表 1) 创建一个新的数据库 db2 CREATE DATABASE db2 CHARACTER SET utf8; 2) 将 db1 数据库中的 emp 表 复制到当前 db2 数据库 1.2 排序 通过 ORDER BY 子句 , 可以将查询出的结果进行排序 ( 排序只…

22.Word:小张-经费联审核结算单❗【16】

目录 NO1.2 NO3.4​ NO5.6.7 NO8邮件合并 MS搜狗输入法 NO1.2 用ms打开文件&#xff0c;而不是wps❗不然后面都没分布局→页面设置→页面大小→页面方向→上下左右&#xff1a;页边距→页码范围&#xff1a;多页&#xff1a;拼页光标处于→布局→分隔符&#xff1a;分节符…

MYSQL 商城系统设计 商品数据表的设计 商品 商品类别 商品选项卡 多表查询

介绍 在开发商品模块时&#xff0c;通常使用分表的方式进行查询以及关联。在通过表连接的方式进行查询。每个商品都有不同的分类&#xff0c;每个不同分类下面都有商品规格可以选择&#xff0c;每个商品分类对应商品规格都有自己的价格和库存。在实际的开发中应该给这些表进行…

python3+TensorFlow 2.x(二) 回归模型

目录 回归算法 1、线性回归 (Linear Regression) 一元线性回归举例 2、非线性回归 3、回归分类 回归算法 回归算法用于预测连续的数值输出。回归分析的目标是建立一个模型&#xff0c;以便根据输入特征预测目标变量&#xff0c;在使用 TensorFlow 2.x 实现线性回归模型时&…

Android --- CameraX讲解

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

CentOS7非root用户离线安装Docker及常见问题总结、各种操作系统docker桌面程序下载地址

环境说明 1、安装用户有sudo权限 2、本文讲docker组件安装&#xff0c;不是桌面程序安装 3、本文讲离线安装&#xff0c;不是在线安装 4、目标机器是内网机器&#xff0c;与外部网络不连通 下载 1、下载离线安装包&#xff0c;并上传到$HOME/basic-tool 目录 下载地址&am…

笔记本搭配显示器

笔记本&#xff1a;2022款拯救者Y9000P&#xff0c;显卡RTX3060&#xff0c;分辨率2560*1600&#xff0c;刷新率&#xff1a;165Hz&#xff0c;无DP1.4口 显示器&#xff1a;2024款R27Q&#xff0c;27存&#xff0c;分辨率2560*1600&#xff0c;刷新率&#xff1a;165Hz &…

DeepSeek R1 linux云部署

云平台&#xff1a;AutoDL 模型加载工具&#xff1a;Ollama 参考&#xff1a;https://github.com/ollama/ollama/blob/main/docs/linux.md 下载Ollama 服务器上下载ollama比较慢&#xff0c;因此我使用浏览器先下载到本地电脑上。 https://ollama.com/download/ollama-linux…

UE5.3 C++ CDO的初步理解

一.UObject UObject是所有对象的基类&#xff0c;往上还有UObjectBaseUtility。 注释&#xff1a;所有虚幻引擎对象的基类。对象的类型由基于 UClass 类来定义。 这为创建和使用UObject的对象提供了 函数&#xff0c;并且提供了应在子类中重写的虚函数。 /** * The base cla…

在排序数组中查找元素的第一个和最后一个位置(力扣)

一.题目介绍 二.题目解析 使用二分进行查找 2.1处理边界情况 如果数组为空&#xff0c;直接返回 [-1, -1]&#xff0c;因为无法找到目标值。 int[] ret new int[2]; ret[0] ret[1] -1; if (nums.length 0) return ret; 2.2查找左端点&#xff08;目标值开始位置&#…

Native Memory Tracking 与 RSS的差异问题

一 问题现象 前一段时间用nmt查看jvm进程的栈区占用的内存大小。测试代码如下 public class ThreadOOM {public static void main(String[] args) {int i 1;while (i < 3000) {Thread thread new TestThread();thread.start();System.out.println("thread : "…

知识库管理如何推动企业数字化转型与创新发展的深层次探索

内容概要 在当今数字化转型的大背景下&#xff0c;知识库管理日益显现出其作为企业创新发展的核心驱动力的潜力。这种管理方式不仅仅是对信息的存储与检索&#xff0c;更是一种赋能&#xff0c;以提升决策效率和员工创造力。企业能够通过系统地整合和管理各类知识资源&#xf…

《DeepSeek 网页/API 性能异常(DeepSeek Web/API Degraded Performance):网络安全日志》

DeepSeek 网页/API 性能异常&#xff08;DeepSeek Web/API Degraded Performance&#xff09;订阅 已识别 - 已识别问题&#xff0c;并且正在实施修复。 1月 29&#xff0c; 2025 - 20&#xff1a;57 CST 更新 - 我们将继续监控任何其他问题。 1月 28&#xff0c; 2025 - 22&am…

DeepSeek-R1本地部署笔记

文章目录 效果概要下载 ollama终端下载模型【可选】浏览器插件 UIQ: 内存占用高&#xff0c;显存占用不高&#xff0c;正常吗 效果 我的配置如下 E5 2666 V3 AMD 590Gme 可以说是慢的一批了&#xff0c;内存和显卡都太垃圾了&#xff0c;回去用我的新设备再试试 概要 安装…

C++中常用的十大排序方法之1——冒泡排序

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C中常用的排序方法之——冒泡排序的相关…

数据结构实战之线性表(一)

一.线性表的定义和特点 线性表的定义 线性表是一种数据结构&#xff0c;它包含了一系列具有相同特性的数据元素&#xff0c;数据元素之间存在着顺序关系。例如&#xff0c;26个英文字母的字符表 ( (A, B, C, ....., Z) ) 就是一个线性表&#xff0c;其中每个字母就是一个数据…

Spring Boot项目如何使用MyBatis实现分页查询及其相关原理

写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油&#xff0c;冲鸭&#x…

【项目初始化】

项目初始化 使用脚手架创建项目Vite创建项目推荐拓展 使用脚手架创建项目 Vite Vite 是一个现代的前端构建工具&#xff0c;它提供了极速的更新和开发体验&#xff0c;支持多种前端框架&#xff0c;如 Vue、React 等创建项目 pnpm create vuelatest推荐拓展