源于牛客听邓巨巨课时的笔记
动态规划原理——分类加法原理,分布乘法原理
分类加法原理:
做一件事,完成它可以有n类方法,在第一类方法中有m1种不同的方法,在第二类方法中有m2种不同
的方法,在第二类方法中有m2种不同的方法,........,在第n类方法中有mn种不同的方法,那么完成这件事
共有N=m1+m2+m3+.....+mn种不同的方法
//走楼梯斐波那契
分布乘法原理:
做一件事,完成它需要分成n个步骤,做第一步有m1种不同的方法,做第二步有m2种不同的方法,......
做第n步有mn种不同的方法,那么完成这件事共有N=m1*m2*m3*.......*mn种不同的方法
//保证每一步最优的方法能推出最后的最优解的话复杂度就是O(n)不需要每一种方法都看
动态规划定义;
动态规划是解决多阶段决策过程中最优化问题的一种方法
阶段;
把问题分成几个相互关系有顺序的几个阶段,这些环节即称为阶段//与搜索有点联系感觉
状态:
某一阶段的出发位置称为状态。通常一个阶段包括若干状态//往下推的点
决策:
从某阶段的一个状态演变到下一个阶段某状态的选择。
策略:
从开始到终点的全过程中,由每段决策组成的决策序列称为全过程策略,简称策略
//最优解的路径
如何求解最优解路径//记住上一个状态,在递归返回的时候输出
状态转移方程:
前一阶段的终点就是后一阶段的起点,前一阶段的决策选择导出了后一阶段的状态
,这种关系描述了由i阶到i+1阶段状态的演变规律,称为状态转移方程
形如:
f[i]=f[i-1]+f[i-2];
f[i,j]=max(f[i-1,j],f[i-1,j-1])+a[i,j]
等等
动态规划适用的基本条件——具有相同子问题
首先我们要保证这个问题能够分解出几个子问题,并且能够通过这些子问题来解决这个问题
其次,将这些子问题作为一个新的问题,他也能分解成相同的子问题进行求解
也就是说假设说我们一个问题被分解为了A,B,C三个部分,那么这A,B,C分别也能被分解为A1,B1,C1三个部分而不是D,E,F三个部分
也就是说A可以分为A1,B1,C1;
B可以分为A1,C1;C可以分为A1,C1;
都是可以的能少分出来不合题意的但不能多分出来D,E,F
//跟搜索很接近但是用dp的话相当于对每个出现的点进行了记录,可以在递归求解已经知道的子问题时
//直接使用结果,相当于记忆化搜索
动态规划适用的基本条件——满足最优子结构
问题的最优解包含着他的子问题的最优解。即不管前面策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策
F[i]表示从起点走到i的路径长度%4得到的最小长度如果这样定义状态就无法用动态规划求解说明状态设置错误
//定义出来的状态要始终满足我使用最优解来推最优解保证由不是最优解推出来的结果也不能是最优解
但是我们可以设f[i][0,1,2,3]来表示在第i步是否会出现0,1,2,3这四个余数相当于总结了过去的步骤对现在步骤的影响,再通过现在的余数推出下次可能出现的余数,所以说状态的转移是十分重要的
动态规划适用的基本条件——满足无后效性
过去的步骤只能通过当前的状态影响未来的发展,当前的状态是历史的总结。这条特征说明动态规划只适用于解决当前决策与过去状态无关的问题。状态,出现在决策的任何一个位置,它的地位相同,都可以实施相同的策略,这就是无后效性的内涵
这是动态规划中极为重要的一点,如果当前问题的具体决策,会对解决其他未来的问题产生影响,就无法保证决策的最优性
//走楼梯加上一个条件,走到50级台阶不能走第100级台阶该如何总结过去
f[i][0|1]表示走第i级台阶是否要经过第50级台阶需要的话是1,不需要的话是0;
i<50 f[i][0]=f[i-1][0]+f[i-2][0] ,f[i][1]=0
i=50 f[50][0]=0; f[50][1]=f[48][1]+f[47][1]
50<i<100 f[i][0]=f[i-1][0]+f[i-2][0] ;f[i][1]=f[i-1][1]+f[i-2][1]
i=100 f[100][0]=f[i-1][0]+f[i-2][0],f[100][1]=0;
做动态规划的一般步骤
First 结合原问题和子问题确定状态
(我是谁?我在哪?)
题目在求什么?要求出这个值我们需要知道什么?什么是影响答案的因素?
(一维描述不完就二维,二维不行就三维四维)
状态的参数一般有
- 描述位置的,前(后)i单位,第i到第j单位,坐标为(i,j),第i个之前(后)且必须取第i个等等
- 描述数量的:取i个,不超过i个,至少i个等
- 描述对后有影响的:状态压缩,一些特殊的性质
Third
考虑要不要优化