当前位置: 首页 > news >正文

蓝桥杯常用算法介绍:动态规划(DP)

蓝桥杯快到了,很多小伙伴私信小编,想让我介绍一些基础的算法,那么今天它来了!

动态规划是一种通过将复杂问题分解为重叠子问题,并记录子问题解来避免重复计算的方法。其核心是状态定义状态转移方程。在竞赛中,DP常用于解决最优化问题(如最大值、最小值)或计数问题(如路径总数)。典型的应用场景包括背包问题、最长子序列、路径规划等。


洛谷题目推荐:P1048 [NOIP2005 普及组] 采药

题目链接:P1048 采药
题目大意:有 T 秒时间采药,药田中有 M 株草药,每株草药需要 t[i] 秒采摘,价值为 w[i]。求在规定时间内能采到的草药最大总价值。


题目分析

  1. 问题转化:经典的 01背包问题。将时间视为背包容量,草药视为物品,目标是选出物品使得总重量不超过容量且总价值最大。

  2. 状态定义:定义 dp[j] 表示使用 j 秒时间能获得的最大价值。

  3. 状态转移:对每株草药 i,从后向前遍历时间 j(避免重复选取):

    dp[j] = max(dp[j], dp[j - t[i]] + w[i]);

  4. 初始化dp 数组初始化为 0,表示未选择任何草药时的价值为 0。

 关键代码解读(C++)

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

const int MAXT = 1005;
int dp[MAXT]; // dp[j]: 使用j秒的最大价值
int t[105], w[105]; // 每株草药的时间和价值

int main() {
    int T, M;
    cin >> T >> M;
    for (int i = 1; i <= M; i++) {
        cin >> t[i] >> w[i];
    }

    // 动态规划核心
    for (int i = 1; i <= M; i++) { // 遍历所有草药
        for (int j = T; j >= t[i]; j--) { // 倒序更新,防止重复选取
            dp[j] = max(dp[j], dp[j - t[i]] + w[i]);
        }
    }

    cout << dp[T] << endl; // 输出最大价值
    return 0;
}

 

代码解析

  1. 输入处理:读取总时间 T 和草药数量 M,存储每株草药的时间和价值。

  2. 动态规划过程

    • 外层循环:遍历每株草药,逐个考虑是否选择。

    • 内层循环:从 T 倒序遍历到 t[i],确保每个草药最多被选一次。

    • 状态转移dp[j] 取“不选当前草药”和“选当前草药”中的最大值。

  3. 输出结果dp[T] 即为在 T 秒内能获得的最大价值。


注意事项

  • 倒序遍历的意义:正序遍历会导致同一株草药被重复选取(完全背包问题),倒序保证每个物品只选一次。

  • 空间优化:使用一维数组代替二维数组,降低空间复杂度至 O(T)

  • 边界条件:当 j < t[i] 时无法选择当前草药,直接跳过。


扩展思考

动态规划的难点在于如何定义状态找到状态转移方程。本题中,背包容量(时间)和物品价值(草药)的模型非常典型,类似的问题可以抽象为“资源分配”问题。例如:

  • 资金预算分配(最大利润)

  • 时间安排(最多任务数)

  • 容器装载(最大利用率)

通过练习类似题目(如洛谷 P1060 [NOIP2006 普及组] 开心的金明),可以进一步掌握一维背包问题的变种。


文章转载自:
http://amberite.ciuzn.cn
http://bimetallist.ciuzn.cn
http://acquired.ciuzn.cn
http://blueness.ciuzn.cn
http://appeasable.ciuzn.cn
http://attributive.ciuzn.cn
http://autograft.ciuzn.cn
http://ceraceous.ciuzn.cn
http://chrismon.ciuzn.cn
http://british.ciuzn.cn
http://airproof.ciuzn.cn
http://brave.ciuzn.cn
http://cerebromalacia.ciuzn.cn
http://basel.ciuzn.cn
http://anticholinesterase.ciuzn.cn
http://broider.ciuzn.cn
http://began.ciuzn.cn
http://cedarn.ciuzn.cn
http://apprentice.ciuzn.cn
http://bedtime.ciuzn.cn
http://asteriated.ciuzn.cn
http://aquatic.ciuzn.cn
http://assumed.ciuzn.cn
http://arresting.ciuzn.cn
http://appropriable.ciuzn.cn
http://athwartship.ciuzn.cn
http://avigator.ciuzn.cn
http://beardless.ciuzn.cn
http://apf.ciuzn.cn
http://barbule.ciuzn.cn
http://www.dtcms.com/a/110252.html

相关文章:

  • 自动驾驶中的实时挑战:如何优化车辆动力学模型
  • YOLO系列论文图表绘制代码
  • BFC特性,开启BFC的方法,怪异盒子模型
  • 如何用 Three.js 和 Vue 3 实现 3D 商品展示
  • Java面试黄金宝典31
  • C语言--统计字符串中最长的单词
  • [leetcode]queue的操作的回顾
  • 【CMOS输出缓冲器驱动强度】
  • 系统架构设计理论之架构风格与模式(分层、MVC、微服务、事件驱动)
  • Android URL中+转义之后导致服务器请求无法获得正确的参数值
  • LeetCode算法题(Go语言实现)_28
  • 【电平转换原理】
  • WinDbg. From A to Z! 笔记(下)
  • 大坑!GaussDB数据库批量插入数据变只读
  • ctfshow _萌新 萌新_密码篇
  • 常见集合篇(五)深入解析 HashMap:从原理到源码,全方位解读
  • 青铜与信隼的史诗——TCP与UDP的千年博弈
  • 【JavaScript】闭包小练习(数字范围起始值和结束值)
  • RHCSA Linux 系统创建文件
  • Vim操作指令全解析
  • 质检LIMS实验室系统在环保技术企业的应用 环保技术研发场景的特殊性需求
  • C++高效读取大规模文本格式点云(windows)
  • 手机归属地查询Api接口,数据准确可靠
  • 根据时间范围得出雪花算法(snowflake)ID的工具类-基于时间反推ID范围
  • AiCube 试用 - 创建流水灯工程
  • 有瓶颈设备的多级生产计划问题:基于Matlab的深度解析与实践
  • LeetCode 解题思路 31(Hot 100)
  • 八. 深入理解 Java 继承:概念、应用与最佳实践
  • Error:java: 程序包lombok不存在
  • 基于springboot+vue的停车场管理系统