动态规划入门

  • 五、动态规划入门
    • 1、动态介绍
      • 1.1动态规划基本思路
      • 1.2 动态规划基本概念
        • 1.2.1 阶段
        • 1.2.2 状态
        • 1.2.3 决策
        • 1.2.4 状态转移方程
        • 1.2.5 策略
      • 1.3 动态规划的优化原理与无后效性
        • 1.3.1 最优化原理
        • 1.3.2 无后效性
    • 2、动态规划问题
      • 2.1 可乐机回家问题
        • 2.1.1 问题描述
        • 2.1.2 解题思路
        • 2.1.3 代码实现
      • 2.2 蒜头君下山问题
        • 2.2.1 问题描述
        • 2.2.2 解题思路
        • 2.2.3 代码实现
      • 2.3 三维的蒜头君回家问题
        • 2.3.1 问题描述
        • 2.3.2 解题思路
        • 2.3.3 代码实现

五、动态规划入门

1、动态介绍

1.1动态规划基本思路

动态规划是编程解题的一种重要手段,1951年美国数学家R.Bellman等人,根据一类多阶段问题的特点,把多阶段决策问题变成一系列相互联系的单阶段问题,然后逐个解决。与此同时,他提出这类问题的最优化原理,从而创建了解决最优化问题的一种新方法:动态规划。
动态规划算法通常用于求解某种最优性质的问题。
我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要被计算过,就讲其结果填入表中。这就是动态规划法的基本思路。

1.2 动态规划基本概念

1.2.1 阶段

把所给问题的求解过程恰当地分成若干个相互联系的阶段,以便于求解。过程不同,阶段数就可能不同。描述阶段的变量称为阶段变量,常用 表示。阶段的划分,一般是根据时间和空间的自然特征来划分,但要便于把问题的过程转化为多阶段决策的过程。

1.2.2 状态

状态表示每个阶段开始面临的自然状况或客观条件,它不以人们的主观意志为转移,也称为不可控因素。通常一个阶段有若干个状态,状态通可以用一个或一组数来描述,称为状态变量。

1.2.3 决策

表示当过程处于某一阶段的某个状态时,可以做出不同的决定,从而确定下一阶段的状态,这种决定称为决策。不同的决策对应着不同的数值,描述决策的变量称决策变量。

1.2.4 状态转移方程

动态规划中本阶段的状态往往是上一阶段的状态和上一阶段的决策的结果,由第 i段的状态dp[i],和决策 u[i]来确定第 i+1段的状态。状态转移表示为F(i + 1) = T(f(i), u(i)) ,称为状态转移方程。

1.2.5 策略

各个阶段决策确定后,整个问题的决策序列就构成了一个策略,对每个实际问题,可供选择的策略有一定范围,称为允许策略集合。允许策略集合中达到最优效果的策略称为最优策略

1.3 动态规划的优化原理与无后效性

1.3.1 最优化原理

一个过程的最优决策具有这样的性质:即无论其初始状态和初始决策如何,其今后诸策略对以第一个决策所形成的状态作为初始状态的过程而言,必须构成最优策略”。也就是说一个最优策略的子策略,也是最优的。

1.3.2 无后效性

如果某阶段状态给定后,则在这个阶段以后过程的发展不受这个阶段以前各个状态的影响。

2、动态规划问题

2.1 可乐机回家问题

2.1.1 问题描述

可怜的可乐机要回家,已知小可乐机在 左下角 (1,1) 位置,家在 右上角 (n,n) 坐标处。小可乐机走上一个格子 (i,j) 会花费一定的体力 a[i][j],而且小可乐机只会往家的方向走,也就是只能往上,或者往右走。小可乐机想知道他回到家需要花费的最少体力是多少, 求你帮帮小可乐机吧qwq

例如下图所示,格子中的数字代表走上该格子花费的体力:

2.1.2 解题思路

对于该图来说,最优策略已在图上标出,最少花费体力为:3 + 2 + 4 + 3 = 123 + 2 + 4 + 3 = 12。

我们把走到一个点看做一个状态,对小可乐机来说,走到一个点只有两种方式,一个是从下面走到该点,一种是从左边走到该点。那么点 (i,j) 要么是从 (i-1,j) 走到 (i,j),要么是从点 (i,j-1) 走到 (i,j)。

所以从哪个点走到 (i,j) 就是一个 决策。接下来,我们用 dp(i,j) 来代表走到点 (i,j) 一共花费的最少体力。
我们需要花费最少力气走到家,所以可以得到状态转移方程:dp(i,j) = min(dp(i-1,j), dp(i,j-1)) + a[i][j] 。根据转移方程,我们可以推出走到每个点花费的最少体力。

对于图中的边界点,要在转移前加上判断是否为边界,如:点 (1,3) 只能从点 (1,2) 走过来,点 (3,1) 只能从点 (2,1) 走过来等等。

动态规划的题目的核心是写出状态转移方程,对于一个动态规划的题目,如果我们能写出转移方程那么代码实现就变得简单多了。大部分的动态规划题目,在计算出转移方程后,可以用类似于递推的循环结构,来写出代码。

2.1.3 代码实现

#include<iostream>
#include<algorithm>
using namespace std;
int a[100][100]; // a数组代表在点(i,j)花费的体力
int dp[100][100]; // dp数组代表走到点(i,j)一共花费的最少体力
int main(){int n;cin>>n;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++){cin>>a[i][j];}}dp[1][1] = 0;//先把初始边界赋值好,再利用递推进行求解for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++){if (i == 1 && j == 1){continue;} else if (i == 1){ //边界点 dp[i][j] = dp[i][j-1] + a[i][j];} else if (j == 1){  //边界点dp[i][j] = dp[i-1][j] + a[i][j];} else {dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + a[i][j]; //转移方程}}}cout<<dp[n][n]<<endl;return 0;

2.2 蒜头君下山问题

2.2.1 问题描述

蒜头在玩一款游戏,他在一个山顶,现在他要下山,山上有许多水果,蒜头每下一个高度就可以捡起一个水果,并且获得水果的能量。山的形状如图所示:
3
1 2
6 2 3
3 5 4 1
这是一个高度为4的山,数字代表水果的能量。每次下一个高度,蒜头需要选择是往左下走,还是往右下走。例如:对于上图的情况,蒜头能获得的最大能量为,3+1+6+5=15。现在,蒜头希望你能帮他计算出下山能获得的最大能量。

2.2.2 解题思路

状态转移方程:f[i][j]=f[i][j]+max(f[i-1][j],f[i-1][j])

2.2.3 代码实现

#include<iostream>
using namespace std;
const int N=1e3+9;
const int int=1000000000;
int f[N][N];
int main(){int n;cin>>n;for(int i=1;i<=n;++n){for(int j=1;j<=i;==j){cin>>f[i][j];}}int ma=-inf;//定义ma表示最后的答案,并初始化为负无穷for(int i=1;i<=n;==i){//递推式for(int j=1;j<=i;==j){f[i][j]+=max(f[i-1][j],f[i-1][j-1]);if(i==n){//在最后一行找最大值ma=max(f[i][j],ma)}}}if(ma==-inf){ma=0;}cout<<ma<<endl;retrun 0;
}

2.3 三维的蒜头君回家问题

2.3.1 问题描述

蒜头君要回家(0,0,0),且值蒜头君当前位置(x,y,z)希望能尽快回到家中,请你帮他计算出回家所需要的最短路程。蒜头君生活的城市可以看做是一个 xyz三维的网格,其中有道路有障碍,钥匙和家所在的地方可以看做是道路,可以通过。蒜头君可以在城市中沿着上下左右前后6个方向移动,移动一个格子算做走一步。

2.3.2 解题思路

在做多维动态规划时,第一步是描述事物,在描述的时候先不必管我们使用空间的大小。当我们可以准确描述清楚一个物体的各个状态的时候,在考虑优化,看看有没有哪个描述是没有必要的,哪个描述是可以通过另外一个值表示。
当多维空间的时候,不能像二维空间那样找规律,这时候需要自己的推理,写出递推方程式。

递推式:f[i][j][k]=min(f[i-1][j][k],f[i][j-1][k],f[i][j][k-1])+f[i][j][k])+f[i][j][k]

2.3.3 代码实现

#include<iostream>
using namespace std;
const int N=1e2+9;
const int inf = 1000000000;int f[N][N][N];
int main(){int x,y,z;cin>>x>>y>>z;for(int i=0;i<=x;++i){//接收数据for(int j=0;j<=y;++j){for(int k=0;k<=z;++k){cin>>f[i][j][k];}}}for(int i=0;i<=x;++i){for(int j=0;j<=y;++j){for(int k=0;k<=z;++k){int mi=inf;//定义一个变量初始值为正无穷大,保存转移过来的三个状态的最小值if(i!=0){mi=min(mi,f[i-1][j][k])//找f[i-1][j][k]是否最小}if(j!=0){mi=min(mi,f[i][j-1][k])//找f[i][j-1][k]是否最小}if(k!=0){mi=min(mi,f[i][j][k-1])//找f[i][j][k-1]是否最小}if(mi!=inf){//通过吗mi是否变化判断f[i][j][k]仍为本身f[i][j][k]+=mi}}}}cout<<f[x][y][z]<<endl;return 0;
}

LQ训练营(C++)学习笔记_动态规划入门相关推荐

  1. LQ训练营(C++)学习笔记_常见动态规划模型

    常见动态规划模型 六.常见动态规划模型 1.最大字段和 1.1 概念描述 1.2动态规划算法分析 1.3 代码实现 2.最长上升子序列(LIS) 2.1 概念描述 2.2 算法分析 2.3 代码实现 ...

  2. LQ训练营(C++)学习笔记_背包问题

    背包问题 七.背包问题 1.01背包问题 1.1 问题描述 1.2 问题分析 1.3 代码实现 1.4 代码优化写法 2.多重背包问题 2.1 题目描述 2.2 问题分析 2.3 代码实现 2.4 空 ...

  3. LQ训练营(C++)学习笔记_广度优先搜索

    这里写目录标题 四.广度优先搜索 1.队列的概念 2.小朋友报数问题 2.1 问题描述 2.2 代码实现 3.广度优先搜索概念 4.走迷宫问题 4.1 问题描述 4.2 代码实现 5.过河卒问题 5. ...

  4. LQ训练营(C++)学习笔记_深度优先搜索

    深度优先搜索 三.深度优先搜索 1.普通深度优先搜索 1.1 迷宫问题描述 1.2 代码实现 2.抽象深度优先搜索问题 2.1 和为K问题 2.1.1 问题描述 2.1.2 解题思路 2.1.3 代码 ...

  5. LQ训练营(C++)学习笔记_枚举算法

    枚举算法 一.枚举算法 1.枚举的概念 2.枚举的题目特点 3.问题描述 4.代码实现 一.枚举算法 1.枚举的概念 枚举就是根据提出的问题,列出该问题所有可能的解,并在逐一列出的过程中,检验每个可能 ...

  6. LQ训练营(C++)学习笔记_栈与递归

    栈与递归 二.栈与递归 1.栈的概念 2.代码实现栈的数据结构 3.栈stack< T >的方法总结 4.火车出入站问题 5.递归的概念 6.递归方法求n的阶乘 7.汉诺塔问题 二.栈与递 ...

  7. 韩顺平php可爱屋源码_韩顺平_php从入门到精通_视频教程_第20讲_仿sohu主页面布局_可爱屋首页面_学习笔记_源代码图解_PPT文档整理...

    韩顺平_php从入门到精通_视频教程_第20讲_仿sohu首页面布局_可爱屋首页面_学习笔记_源代码图解_PPT文档整理 对sohu页面的分析 注释很重要 经验:写一点,测试一点,这是一个很好的方法. ...

  8. oracle 删除awr报告,学习笔记:Oracle awr入门 深入了解AWR报告

    天萃荷净 深入了解AWR报告,ASH与AWR报告的官方说明,数据库进程和性能视图获取 1.AWR与ASH概念 1.ASH 若是一个普通的会话(我是指没有大量地耗费资源),则对于性能调整来说无足轻重.但 ...

  9. UE4_Niagara基础2_学习笔记_枪火制作

    教程地址:https://www.bilibili.com/video/BV1fE411b7at 一套基础入门且案例非常完整的教程,能够比较快的走一遍制作流程 讲师:贾越(Epic Fornite T ...

最新文章

  1. linux服务器的搭建配置与应用,linux服务器的搭建与配置
  2. crontab 用法
  3. cross--向量或矩阵的叉乘
  4. linux awk命令用途,Linux:“awk”命令的妙用
  5. js 操作vuex数据_Vue.js中使用Vuex实现组件数据共享案例
  6. 【今日CV 计算机视觉论文速览 第107期】Mon, 29 Apr 2019
  7. python timer 死掉_Python定时事件 Timer sched
  8. java多线池_java多线程之线程池
  9. 数据分析需要的数据集
  10. 为什么做AI的都选Python?
  11. linux系统下载r软件安装,Linux安装R语言包
  12. java全栈开发工程师面试题总结
  13. mysql分区语录_MYSQL分区管理
  14. (一百五十一)Android P 真正创建sta iface的地方
  15. 华为USG防火墙搭建IPsec***实战
  16. python输出保留两位小数怎么表示_python格式输出的实现方法保留2个小数位
  17. bit,byte,b,B,KB的整理
  18. Redis主从复制架构初步探索 http://www.sxt.cn/info-1750-u-324.html#SXT_h2_11
  19. ARCGIS SERVER 授权
  20. android监控app被杀死,Android App前后台监控

热门文章

  1. html5 markdown,Markdown常用语法
  2. ZooKeeper学习第七期--ZooKeeper一致性原理
  3. github注册之后更新教程
  4. 1067: [SCOI2007]降雨量
  5. 在Linux中发现IP地址冲突的方法
  6. Lucene.Net(转)
  7. python学习三 函数
  8. SQLServer游标简单应用(求分组最小值问题)
  9. 3389端口远程终端服务的全攻略
  10. laravel 数据库获取值的常用方法