首页 > 编程语言 >(C++)DP动态规划

(C++)DP动态规划

时间:2024-03-16 21:35:47浏览次数:29  
标签:状态 方程 背包 C++ 物品 动态 转移 DP

天下苦DP久已。

​ DP非常重要,2022年蓝桥杯应该改名为DP杯,至于2023年那个我觉得应该叫做暴力杯。

​ DP的核心思想在于,通过前面几个状态来推导下一个数据是什么,也就是走一步是一步。其本质实际上是记忆化搜索,但是有些玄学的事情就是,有时候记忆化会因为玄学递归问题TLE,但DP的那四五层for循环就迷之过了。


​ DP题的核心在于两个事情:

一个就是你要知道这题可以DP

​ 是否有后效性,对于某个问题,如果我们只关注某个状态,只关注状态的值,而不关注该状态是如何转移过来的,那么就是一个无后效性的问题,此时可以使用DP解决。

​ 用人话来说就是,只会用上一步计算出下一步,前面其他步骤都不对现在的步骤产生任何影响。

 大问题的最优解可以由小问题的最优解推出,这个性质叫做“最优子结构性质”。

就是说你能从一个小问题一路推到问题本身,就像斐波那契数列一样,你得从1+1开始推,然后一路推到你当前需要的数字里头。

然后就是你要知道怎么得到状态转移方程

​ 这步才是真正麻烦的事情。状态转移方程的目的就是利用前一状态,通过特定但是通用的式子,来得到当前状态的最优答案。但到底用什么做状态,有个很容易理解的事情。很多人都说01背包问题才是DP的经典入门题。我觉得不是。

​ 有请真正经典例题:NOIP2004普及组 花生采摘

​ 题目不再在这里复述了,自个去里头看。但是为什么我说这题才是经典入门题呢?这题能很好并且很简单的体现DP该有的一切。他的状态转移方程原理非常清晰明了:\(f[y][x] = max(上方点最大采摘数, 左方点最大采摘数) + 当前点花生数\)。在方程里,我们可以立刻确认一件事情:状态是位置,方案最优解来自于当前位置的花生数和上一步可以得到的最大花生数。

​ 那么到底什么可以作为状态?你可以把状态转移方程比喻成一个特殊的函数,这个函数需要你输入特定的自变量才能得到结果,而那些自变量就如同构成了坐标轴一样(就好像花生采摘的平面坐标一样)构建了一个坐标系,我们需要用当前的坐标,配合题目条件去计算下一个坐标在哪。用这个思维去看01背包问题 - NOIP2005普及组 采药,到底是什么可以构成我们的坐标系呢?价值要作为答案的输出,所以肯定不是,那么就剩下第几种药和已用的时间,换成裸的01背包描述就是,我们用当前物品编号剩下多少时间组成了自变量,得到了二维的方程。

​ 选用当前物品编号(而不是选用已经选择了多少个物品)作为其中一个状态的原因是,我们需要确认我们选了什么,这样才能从其他状态得到对应的值。如果用的是取了多少个物品,我们并不知道到底取用了哪些物品,那就找不到状态在数组中对应的位置,就没法把状态转移方程推导下去。

​ 那么到了多重背包里呢就是多枚举一下每个物品塞多少个,塞不塞得下,因为多重背包本质就是这个物品重复几次出现而已。至于完全背包问题,则是通过倒着推背包空间来获得解法。

​ 通过以上总结可以发现,可以作为状态的参数必须是可用于计算上/下一个状态是什么,这样才能找到下一个状态位置,搞出状态转移,进而使用状态转移方程计算结果。

标签:状态,方程,背包,C++,物品,动态,转移,DP
From: https://www.cnblogs.com/ComputerEngine/p/18077641

相关文章

  • c++机试一些提示
    1、优先队列的使用,头文件#include;优先队列定义:priority_queue<int,vector<int>,greater<int>>pq;(整数数据类型,小顶堆)。例题:哈夫曼树#include<iostream>#include<queue>usingnamespacestd;intmain(){intn;cin>>n;priority_queue<i......
  • 华为OD机试 C++ -文件缓存系统
    文件缓存系统前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述请设计一个文件缓......
  • 动态代理和反射的基本学习
    今天在跟着视频学习的时候发现老师讲的知识点都只简单的了解过但是没有深入学习,导致在跟着视频敲代码的时候完全不知道自己是在写什么东西。所以决定先把基础补一补再继续跟老师做项目。打算先把自定义注解的编写和解析学好,想要学号这一块,又涉及到了Aop和java中反射的学习,那么话......
  • C++ 枚举
    C++枚举5.4.1普通枚举枚举的定义:,枚举类型是通过enum关键字定义的,比如定义颜色类型enumColor{RED,//默认值为0GREEN,//默认值为1BLUE//默认值为2};ColormyColor=RED;注意:(1)括号内为以逗号分隔,大括号结尾要有分号(2)枚举类型就相当于......
  • 10. C++关键字virtual用法
    1.C++关键字:virtual用法1.1概念virtual是C++OO机制中很重要的一个关键字。主要用在两个方面:虚函数、纯虚函数和虚基类、虚继承。1.2虚函数virtual放在函数的返回值前面,用于表示该类成员函数为虚函数;父类虚函数前的virtual必须写;子类虚函数前的virtual可以省略,因为不......
  • 使用c++容器string相关完成
    //把邮箱地址字符串[email protected],取出其中用户名字符串打印stringgetUsername(string&s){   intpops=s.find('@');   stringusername=s.substr(0,pops);   returnusername;}//大小写转换 使用标准库提供俩函数,单个字符为操作对象stringstr=......
  • 详解MySQL的MVCC(ReadView部分解析C++源码)
    文章目录1.什么是MVCC2.MVCC核心组成(三大件)2.1MVCC为什么需要三大件3.隐藏字段4.undolog4.1模拟版本链数据形成过程5.ReadView5.1m_ids5.2m_creator_trx_id5.3m_low_limit_id5.4m_up_limit_id5.5可见性分析算法6.MVCC流程模拟6.1RC隔离级别6.2RR隔离......
  • 动态规划专项训练记录 2024.3
    PathsontheTree若使分数最大,则尽量每条路径都到叶子,看到题目说绝对值差不超过1,可以发现是要尽量平均分配,设余r条路径既然要最大化贡献且剩下的路径要不重复的分配,那就选取前r条从该节点到叶子节点权值和最大的链,递归求取但有一种情况,若在点u选了路径t,在fa再次选择,就会不满......
  • C++学习笔记——002
    在一个类里建立一个const时,不能给他初值:classfoo{public:foo():i(100){}private:constinti=100;//错误!!!};//可以通过这样的方式来进行初始化foo::foo():i(100){} classTest{public:Test():a(0){}enum{size1=100,size2=200};......
  • C++类模板与友元详解
    C++模板下面分四种情况分别讨论。1.函数、类、类的成员函数作为类模板的友元函数、类、类的成员函数都可以作为类模板的友元。程序示例如下:void Func1() {  }class A {  };class B{public:    void Func() { }};template <class T>class Tmpl{......