动态规划的基本概念
阶段和阶段变量
将问题的全过程恰当地分为若干个相互联系的阶段。阶段的划分一般根据时间和控件的自然特征去划分,阶段的划分要吧问题转化为多阶段决策问题。
状态和状态变量
通常一个阶段包含若干个状态
状态可有变量表述
决策 决策变量和决策允许集合
在对问题的处理中做出的每种选择性的行动就是决策,即从该阶段的每一个阶段出发,通过一次选择性的行动转移至下一阶段的相应阶段。
在实际问题中,决策变量的取值往往限制于某一个范围内
策略和最优策略
所有阶段一次排列构成问题的全过程。
全过程中各阶段决策变量所组成的有序总体称为策略
在实际问题中,从决策允许集合中找出最优效果的策略称为最优策略
状态转移方程
前一阶段的终点就是后一阶段的起点,对前一阶段的状态做出某种决策,产生后一种阶段的状态,这种关系描述了从i阶段到i+1阶段状态的演变规律,称为状态转移方程.
例子1
从n个数中取出k个数,使得他们的和最大。
f[i][j]表示现在考虑到第i个数,已经选出了j个数
为了详解动态规划,不选用常用做法
阶段:i表示1~i个数
状态:j 选了几个数
决策:选不选?
策略 :值最大
状态转移方程:
例子2
从n个数中找出最长的上升子序列
f[i][j]表示目前考虑到第i个数,子序列中最后一个数是j的最长上升子序列长度。
阶段:i
状态:j
决策:对第i个数取还是不取
策略:最大化取序列
状态转移方程:
考虑a[1~n]
f[i][a[[i]]考虑a[i]选取,那就要在a[i]的前面选取一个最大的数,即可以用1+max{f[i-1][j]|j<=a[i]}
要是不考虑a[i]选取,f[i][j]=f[i-1][j];
动态规划的性质
什么样的“多阶段决策问题”才可以用动态规划的方法来求解呢?
必须满足两个条件:
最优化原理
无后效性原则
最优化原理
例如f[n][k]取最大,取决于f[n-1][k],那么就要a[n]+f{n-0][k-1]最大。
无后效性原则
就是f[n-1][k]中之后这个状态我取不取都无影响,也就是之前已经是最优解,不能用之前的影响未来
不符合上述两个原则的,不能用动态规划来解
动态规划的设计方法
正推:从初始状态开始,通过对中间阶段的决策的选择,达到结束状态。我们也称递推。
反推:从结束状态开始,通过对中间阶段的决策的选择,达到开始状态,我们可以把这种方法看出记忆化搜索。
dp(n)=dp(n-1)*n;
把每一步dp(n)存在一个数组里面,这样就能保证下次访问时从数组中取出来,不用在此递归。
我们只要在开始的时候,设立一个边界值就可。
动态规划设计方法的一般模式
动态规划与记忆化搜索
记忆化搜索
实现一个函数,用"搜索" 的方法实现DP的更新。
通常用于转移顺序不方便人为确定的DP
例题 数塔
每一层就有一个阶段,有若干个状态,某一个状态可以转移到下面两个点,,一直到最后一层
设f[i][j]表示第i行第j列的最大值
正常DP:
走到[i][j]的最大值
这样算有一个致命缺点,每次计算都会进行一次递归,这就是记忆化的来源,那对于计算过的dp(i,j),我们用f[i][j]来存
f初始化为-1
int dp(int i,intj)
{
if(i==0)
return 0;
if(f[i][j]>=0)
return f[i][j];
f[i][j]=a[i][j]+max(dp(i-1,j),dp(i-1,j-1));
return f[i][j];
}
例题二
int dp(int i, int j)//从i j出发最远能滑行的距离
{
if (f[i][j] > 1)
return f[i][j];//返回已经存储的值
for (int k = 0; k < 4; k++)//枚举四个方向可以转移
{
int x = i + dx[k], y = j + dy[k];//每个方向上的唯一
if (x >= 1 && x <= r && y >= 1 && y <= c)//在地图里面
{
if (a[i][j] > a[x][y])//满足高度在下降
f[i][j] = max(f[i][j], dp(x, y) + 1);//从x,y能滑的点在加一
}
return f[i][j];
}
}
这样就通过记忆化搜索更新,使用记忆化搜索比较直观一些,因为使用了记忆化,那我们的时间复杂度也有了保证,因为每次都进行了存储。
for (int i = 1; i <= r; i++)
{
for (int j = 1; j <= c; j++)
f[i][j] = 1;
}
int ans = 0;
for (int i = 1; i <= r; i++)
for (int j = 1; j <= c; j++)
ans = max(dp(i, j), ans);
printf("%d\n", ans);
博主今天晚上刚刚接触的动态规划,脑子有点懵,如有错误还请指教!!!!!!!!!!