跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C/C++ 算法入门:一维动态规划基础实战

动态规划核心在于状态定义与转移方程。通过泰波那契数、三步问题、最小花费爬楼梯及解码方法四道经典例题,演示一维 DP 的解题五步法:状态表示、转移方程、初始化、填表顺序及返回值。重点讲解空间优化技巧与边界处理,帮助读者掌握从暴力递归到 DP 优化的实战思路。

CryptoLab发布于 2026/3/26更新于 2026/10/1588 浏览
C/C++ 算法入门:一维动态规划基础实战

动态规划基础

动态规划(Dynamic Programming)的核心在于将复杂问题分解为重叠子问题,通过存储中间状态避免重复计算。简单来说,它包含两个要素:某种状态的公式 + 提前求出来值的容器。我们计算出当前位置的值放入容器中供后续使用,初始值通常由题目直接给出。

严格定义下:动态规划 = 状态定义 + 状态转移方程 + 初始条件 + 状态存储

解题五步法

掌握以下五个步骤,能帮助你系统性地解决大部分 DP 问题:

  1. 状态表示:明确 dp[i] 的含义。通常结合经验与题目要求,例如'以 i 位置结尾'或'前 i 个元素的最优解'。
  2. 状态转移方程:这是最关键的一步,本质是推导 dp[i] = ?。需根据状态表示和题目逻辑找出当前状态与前序状态的关系。
  3. 初始化:确保填表时不越界,并根据题目设定初始值(如 dp[0], dp[1])。
  4. 填表顺序:保证计算当前状态时,所需的前置状态已计算完成。通常是从左向右或从上到下。
  5. 返回值:根据题意从 dp 表中提取最终结果。

提示:处理边界问题时,适当开辟额外空间(如多开一位)往往能简化代码逻辑。判断多位数字时,建议转换为数值而非单纯字符比较,以避免不可控的边界情况。

实战演练

1. 第 N 个泰波那契数

题目描述:计算第 n 个泰波那契数,其中 T(0)=0, T(1)=1, T(2)=1, T(n)=T(n-1)+T(n-2)+T(n-3)。

思路分析: 这是一个典型的一维 DP 问题。状态表示很直观,dp[i] 即为第 i 个泰波那契数。转移方程直接由定义得出。由于计算 dp[i] 只需要前三个值,我们可以进行空间优化。

核心代码:

class Solution {
public:
    int tribonacci(int n) {
        // 空间优化写法:仅保留前三个变量
        if (n == 0) return 0;
        if (n == 1 || n == 2) return 1;
        
        int a = 0, b = 1, c = 1;
        int ret = 0;
         ( i = ; i <= n; ++i) {
            ret = a + b + c;
            a = b;
            b = c;
            c = ret;
        }
         ret;
    }
};
for
int
3
return
2. 三步问题

题目描述:小孩每次可以走 1、2 或 3 步,问上到 n 阶台阶有多少种方法。结果对 10^9+7 取模。

思路分析: 到达第 n 阶的方法数等于到达 n-1、n-2、n-3 阶的方法数之和。注意本题需要处理取模运算防止溢出,且初始化时需考虑 n 较小的情况。

核心代码:

class Solution {
public:
    int waysToStep(int n) {
        if (n == 1) return 1;
        if (n == 2) return 2;
        if (n == 3) return 4;
        
        vector<int> dp(n + 1);
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 4;
        
        for (int i = 4; i <= n; ++i) {
            dp[i] = ((long long)dp[i - 1] + dp[i - 2] + dp[i - 3]) % 1000000007;
        }
        return dp[n];
    }
};
3. 使用最小花费爬楼梯

题目描述:给定数组 cost,cost[i] 是从楼梯第 i 个台阶向上爬的费用。你可以从索引 0 或 1 开始,求到达楼顶的最小花费。

思路分析: 这里有两种常见的状态定义方式:

  1. 正向推导:dp[i] 表示到达第 i 层的最小花费。dp[i] = min(dp[i-1], dp[i-2]) + cost[i]。注意楼顶在数组末尾之后,所以 dp 数组长度需加 1。
  2. 反向推导:dp[i] 表示从第 i 层出发到达楼顶的最小花费。此时填表顺序从右向左。

核心代码(正向):

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        vector<int> dp(n + 1);
        dp[0] = 0;
        dp[1] = 0;
        
        for (int i = 2; i <= n; ++i) {
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
};
4. 解码方法

题目描述:给定只含数字的字符串,将其解码为字母('A'-'Z' 对应 '1'-'26'),求有多少种解码方法。

思路分析: 这是一个涉及边界判断的 DP 题。对于第 i 位字符:

  1. 如果单独解码有效(1-9),则加上 dp[i-1]。
  2. 如果与前一位组合解码有效(10-26),则加上 dp[i-2]。

技巧:为了统一处理边界,可以将 dp 数组多开一位,利用虚拟节点简化初始化逻辑。特别注意 '0' 的处理以及两位数字的组合范围。

核心代码:

class Solution {
public:
    int numDecodings(string s) {
        int n = s.size();
        if (n == 0 || s[0] == '0') return 0;
        
        vector<int> dp(n + 1);
        dp[0] = 1; // 虚拟节点,辅助计算
        dp[1] = 1;
        
        for (int i = 2; i <= n; ++i) {
            // 单个字符解码
            if (s[i - 1] != '0') {
                dp[i] += dp[i - 1];
            }
            // 两个字符组合解码
            int twoDigit = stoi(s.substr(i - 2, 2));
            if (twoDigit >= 10 && twoDigit <= 26) {
                dp[i] += dp[i - 2];
            }
        }
        return dp[n];
    }
};

总结

通过上述四道题,我们梳理了一维动态规划的通用套路。关键在于准确的状态定义和对边界条件的敏感处理。建议在理解原理的基础上多加练习,培养对子问题的抽象能力。

目录

  1. 动态规划基础
  2. 解题五步法
  3. 实战演练
  4. 1. 第 N 个泰波那契数
  5. 2. 三步问题
  6. 3. 使用最小花费爬楼梯
  7. 4. 解码方法
  8. 总结

更多推荐文章

查看全部
  • Kubernetes 集群可视化管理:Kuboard 部署与实战指南
  • Git 安装与基础配置指南
  • 执行式 AI 核心:API 调用与网络请求基础
  • Python 实现 Markdown 转 Word 文档(markdown+python-docx 方案)
  • 华为 OD 机试:项目排期算法 Java 实现
  • Android 广域网 P2P 语音聊天实战:WebRTC 与 NAT 穿透技术解析
  • 清华团队发布OpenClaw研究报告:AI智能体生态闭环全解析
  • Qwen3 系列模型对比及长上下文训练技术解析
  • 数据结构实战:C 语言循环双向链表实现详解
  • 网络安全入门教程:基础原理与实战指南
  • 基于 Spring Boot 的在线考试系统设计与实现——学生课程实践记录
  • 基于STM32的智能家居安防系统设计与实现
  • VSCode 本地部署 DeepSeek 模型与 CodeGPT 配置指南
  • OpenClaw 框架 30+ 真实场景实战拆解
  • 黑客文化兴起:从少儿编程到加密货币漏洞赏金
  • 前端首屏全链路性能优化:从诊断到落地的完整实践
  • 前端 CI/CD 流程:构建与自动化部署最佳实践
  • Git 版本控制详细使用教程
  • 机器人操作 VLA 模型的强化学习综述
  • 程序员转型 AI 产品经理:核心能力与成长路径

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online