动态规划

什么是动态规划?

动态规划是解决多阶段决策最优化问题的一种思想方法。所谓“动态”,指的是在问题的多阶段决策中,按某一顺序,根据每一步所选决策的不同,将随即引起状态的转移,最终在变化的状态中产生一个决策序列。动态规划就是为了使产生的决策序列在符合某种条件下达到最优。

一、动态规划中的主要概念,名词术语

1 阶段:把问题分成几个相互联系的有顺序的几个环节,这些环节即称为阶段。
2 状态:某一阶段的出发位置称为状态。通常一个阶段包含若干状态。如图1中,阶段3就有三个状态结点4、5、6。
3 决策:从某阶段的一个状态演变到下一个阶段某状态的选择。
4策略:由开始到终点的全过程中,由每段决策组成的决策序列称为全过程策略,简称策略。
5 状态转移方程:前一阶段的终点就是后一阶段的起点,前一阶段的决策选择导出了后一阶段的状态,这种关系描述了由k阶段到k+1阶段状态的演变规律,称为状态转移方程。
6 目标函数与最优化概念:目标函数是衡量多阶段决策过程优劣的准则。最优化概念是在一定条件下找到一个途径,经过按题目具体性质所确定的运算以后,使全过程的总效益达到最优。

二、动态规划问题的数学描述

首先,例举一个典型的且很直观的多阶段决策问题:
[例] 下图表示城市之间的交通路网,线段上的数字表示费用,单向通行由
A->E。试用动态规划的最优化原理求出 A->E 的最省费用。

如图从 A 到 E 共分为 4 个阶段,即第一阶段从 A 到 B,第二阶段从 B 到 C,
第三阶段从 C 到 D,第四阶段从 D 到 E。除起点 A 和终点 E 外,其它各点既是上
一阶段的终点又是下一阶段的起点。例如从 A 到 B 的第一阶段中,A 为起点,终
点有 B1,B2,B3 三个,因而这时走的路线有三个选择,一是走到 B1,一是走到
B2,一是走到 B3。若选择 B2 的决策,B2 就是第一阶段在我们决策之下的结果,
它既是第一阶段路线的终点,又是第二阶段路线的始点。在第二阶段,再从 B2
点出发,对于 B2 点就有一个可供选择的终点集合(C1,C2,C3);若选择由 B2
走至 C2 为第二阶段的决策,则 C2 就是第二阶段的终点,同时又是第三阶段的始
点。同理递推下去,可看到各个阶段的决策不同,线路就不同。很明显,当某阶
段的起点给定时,它直接影响着后面各阶段的行进路线和整个路线的长短,而后 面各阶段的路线的发展不受这点以前各阶段的影响。故此问题的要求是:在各个
阶段选取一个恰当的决策,使由这些决策组成的一个决策序列所决定的一条路
线,其总路程最短。

三、 运用动态规划需符合的条件

任何思想方法都有一定的局限性,超出了特定条件,它就失去了作用。同理,动态规划也并不是万能的。那么使用动态规划必须符合什么条件呢?必须满足最优化原理和无后效性。

1 最优化原理

最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状
态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。

2 无后效性

“过去的步骤只能通过当前状态影响未来的发展,当前的状态是历史的总结”。这条特征说明动态规划只适用于解决当前决策与过去状态无关的问题。状态,出现在策略任何一个位置,它的地位相同,都可实施同样策略,这就是无后效性的内涵。
由上可知,最优化原理,无后效性,是动态规划必须符合的两个条件。

四 、动态规划的计算方法

对于一道题,怎样具体运用动态规划方法呢?

(1)首先,分析题意,考察此题是否满足最优化原理与无后效性两个条件。
(2)接着,确定题中的阶段,状态,及约束条件。
(3)推导出各阶段状态间的函数基本方程,进行计算。

应用举例:数字三角形(洛谷-P1216)

题目描述
观察下面的数字金字塔。

写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。

    7 3   8
8   1   0

2 7 4 4
4 5 2 6 5
在上面的样例中,从 7 \to 3 \to 8 \to 7 \to 57→3→8→7→5 的路径产生了最大

输入格式
第一个行一个正整数 rr ,表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

输出格式
单独的一行,包含那个可能得到的最大的和。

输入输出样例
输入:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出
30

思路:

@顺推:

F[i+1][j] = MAX (F[i][j] + a[i+1][j]);

F[i+1][j+1] = MAX (F[i][j] + a[i+1][j+1]);

@ 逆推:

F[i][j] = MAX (F[i-1][j], F[i-1][j-1]) + a[i][j]; (注意!逆推时要注意边界情况! )

代码如下:
1、顺推:

//T2:数字金字塔-顺推(有点类似于记忆化搜索的思路)
//d数组储存顺序:记录从顶端向底部走的路径最优值(自顶向下)#include<iostream>
#include<string.h>
using namespace std;
int a[1005][1005];//储存数塔
int d[1005][1005];//从该点到底端的最大数字和
int main()
{int i,j,n,ans;while(cin>>n){memset(d,-1,sizeof(d));for(i=0;i<n;i++)for(j=0;j<=i;j++){cin>>a[i][j];}d[0][0]=a[0][0];for(int i=0;i<n-1;++i)for(int j=0;j<=i;++j)//d数组为最优值路径(黑色金字塔,a为源数据数组(紫色金字塔){//分别用最优值来更新左下方和右下方d[i+1][j]=max(d[i+1][j],d[i][j]+a[i+1][j]);//和当前的f[i+1][j]比较d[i+1][j+1]=max(d[i+1][j+1],d[i][j]+a[i+1][j+1]);//和当前的f[i+1][j+1]比较}//答案可能是最后一行的任意一个,所以把最后一行搜索一遍,最大的赋给ansans=0;for(int i=0;i<n;i++)ans=max(ans,d[n-1][i]);cout<<ans<<endl;for(int i=0;i<n;++i){for(int j=0;j<=i;++j){cout<<d[i][j]<<" ";}cout<<endl;}}return 0;
}

2、逆推

//数字金字塔-逆推
//d数组储存顺序:记录从顶端向底部走的路径最优值(自顶向下)
#include<iostream>
#include<string.h>
using namespace std;
int a[1005][1005];//储存数塔
int d[1005][1005];//从该点到底端的最大数字和
int main()
{int i,j,n,ans;while(cin>>n){memset(d,-1,sizeof(d));for(i=0;i<n;i++)for(j=0;j<=i;j++){cin>>a[i][j];}//逆推(自顶向下)d[0][0]=a[0][0];for(int i=1;i<n;i++){d[i][0]=d[i-1][0]+a[i][0];//最左的位置没有左上方d[i][i]=d[i-1][i-1]+a[i][i];//最右的位置没有右上方for(int j=0;j<=i;j++)//在左上方和右上方取较大的d[i][j]=max(d[i-1][j-1],d[i-1][j])+a[i][j];}//答案可能是最后一行的任意一个,所以把最后一行搜索一遍,最大的赋给ansans=0;for(int i=0;i<n;i++)ans=max(ans,d[n-1][i]);cout<<ans<<endl;;for(int i=0;i<n;++i){for(int j=0;j<=i;++j){cout<<d[i][j]<<" ";}cout<<endl;}}return 0;
}

附注:

动态规划相比较于深度搜索算法是一种高效算法。若能成功运用,必会使程序效率,无论时间还是空间,都有着质的飞跃。

掌握好动态规划,关键还是在于理解动态规划算法的基础上,多找一些相关的题进行练习。

NOIP竞赛学习整理--动态规划算法举例P1264相关推荐

  1. ACM竞赛学习整理--模拟算法举例POJ1068

    什么是模拟 仅仅使用较简单的算法和数据结构的题目. 模拟顾名思义,就是按照题目的要求,一步步写出代码. 常见的模拟方法 a.用数学量和图形描述问题 计算机处理的是数学量.若要用计算机解决实际问题,需要 ...

  2. ACM竞赛学习整理开篇之01背包问题

    ACM竞赛学习整理开篇之01背包问题. 最近,偶然的一次机会让我关注信息奥赛的一些内容.发现其中的内容很有趣,是学习编程的一条很好的路径,又能很好地将数学和编程联系到一起.在csdn里看到了不少同好也 ...

  3. ACM竞赛学习整理--矩阵运算

    ACM竞赛学习整理–矩阵运算 了解矩阵类 [任务] 实现矩阵的基本变换 [接口] 结构体:Matrix 成员变量: int n,m 矩阵大小 int a[][] 矩阵内容 重载运算符: +.-.x 成 ...

  4. 动态规划算法实验报告_强化学习之动态规划算法

    如今的强化学习研究大体分为了两个研究学派:一个是以Sutton,Sliver等人为代表的value-based学派,他们主要从值函数近似角度入手去研究强化学习,这也是强化学习早期最初发展起来时沿用的路 ...

  5. ACM竞赛学习指南(算法工程师成长计划)

    算法工程师成长计划 近年来,算法行业异常火爆,算法工程师年薪一般20万-100 万.越来越多的人学习算法,甚至很多非专业的人也参加培训或者自学,想转到算法行业.尽管如此,算法工程师仍然面临100万的人 ...

  6. ACM竞赛学习整理--Gauss求解POJ1166

    这道题目和1830比较类似,1830是求解的个数,这道题目相当于求线性方程组的整数解. 题目主要内容:有9个钟,其中9个操作方法来扳动上面的指针,每个操作每次只能把指针移动90度,且每个操作是对一组钟 ...

  7. 信息学竞赛学习资料整理

    信息学竞赛学习资料整理 一.总结 一句话总结:可以在网上获取各种免费视频资源,网上超多,也可以买书,也可以去刷题网站多做题 1.信息学竞赛书籍推荐? 信息学竞赛一本通 算法导论 组合数学 <CC ...

  8. php算法学习,php算法学习之动态规划

    动态规划程序设计是对解最优化问题的一种途径.一种方法,最终问题的最优解可以通过前面子问题的最优解推导出来. 对于动态规划这个算法,自己学习的还不是很透彻,简单的总结自己学习的感受是: 动态规划思想中融 ...

  9. 学习进度2012-6-26(动态规划算法、Prim算法、Dijkstra算法)

    今天学习下三个算法:动态规划算法.Prim算法.Dijkstra算法,将自己理解的逻辑略作总结. 1.动态规划算法是选取两个字符串的最长子序列的解法作为切入点学习,在公司午休时间将代码写了下,初步测试 ...

最新文章

  1. Java 2实用教程(第五版)耿祥义 全部课后习题答案
  2. 网易游戏2016实习生招聘笔试题目--井字棋
  3. 初窥Go module
  4. 使用 case when进行行列转换
  5. 限制连接数上涨的几个关键因素
  6. Shell break和continue命令
  7. robots.txt文件详解
  8. Java中的List你真的会用吗
  9. 1071元!苹果上架iPhone 11系列智能电池壳:可充电、支持拍照
  10. struts2中的constant配置详解
  11. 普林斯顿微积分读本篇一:函数
  12. 《鸟哥的Linux私房菜》第四版导学
  13. BSOD issue - collect complete memory dump
  14. 这10部功夫片曾拿到金像奖最佳动作设计奖,李连杰主演的就有4部
  15. POI设置excel格式为文本格式
  16. 将正方形矩阵顺时针转动90度(Java)
  17. 如何让手机扫二维码就能阅读PDF
  18. VirtualAPP技术应用及安全分析报告
  19. 【繁中】Python 教學 爬蟲基礎
  20. [LeetCode]844. Backspace String Compare 解题报告(C++)

热门文章

  1. 十一、“由专入分易,由分入专难。”(2020.12.18)
  2. 云炬Qtpy5开发与实战笔记 2PyCharm添加QTDesinger扩展并创建第一个.ui文件
  3. 吐血整理!10 个机器学习教程汇总,爱可可推荐!
  4. Python1:if / while / for...in / break /continue
  5. VTK修炼之道17:图像基本操作_图像信息的访问与修改(vtkImageData)
  6. [OS复习]进程管理2
  7. Delphi与c++ 数据类型对照表(从万一的博客园摘录)
  8. linux的swap增加的二个办法
  9. JavaScript对TreeView的操作全解
  10. __name__ == '__main__' 到底是什么意思