动态规划小结(以采药问题为例)
定义:把一个问题分解为子问题递归求解,并且将中间结果保存以避免重复计算的办法,就叫做“动态规划”。动态规划是解决多阶段决策过程最优化问题的一种方法。
动态规划中的相关概念:
1、阶段
用动态规划求解一个问题时,需要将问题的全过程恰当地划分成若干个相互联系的阶段,以便按一定的次序去求解。阶段的划分一般是根据时间和空间的自然特征来定的,一般要便于把问题转化成多阶段决策的过程。
2、状态
状态表示的是事物某一阶段的性质,状态通过一个变量来描述,这个变量称为状态变量。各个状态之间是可以相互转换的。
3、决策
对问题的处理中做出某种选择性的行动就是决策。在每一个阶段中都需要有一次决策。一次决策就会从一个阶段进入另一个阶段,状态也就发生了转移。
4、策略和最优策略
所有阶段按照约定的决策方法,依次排列构成问题的求解全过程。这些决策的总体称为策略。在实际问题中,从决策允许集合中找出最优效果的策略称为最优策略。
5、状态转移方程
前一阶段的终点就是后一阶段的起点,这种关系描述了由K阶段到K+1阶段状态的演变规律,是关于两个相邻阶段状态的方程,称为状态转移方程,是动态规划的核心。
动态规划算法的一般模式:
① 划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。(在划分阶段时,注意有序或可排序)
② 确定状态和状态变量:将问题发展到各个阶段时所处的各种情况用不同状态表示出来;
③ 确定决策并写出状态转移方程:一般是根据相邻两个阶段各状态之间的关系来确定决策;
④ 寻找终止条件:给出的状态转移方程是一个递推式,必须有一个递推的终止条件;
下面举一个自己做过的例子:
采药问题
1.首先以采摘的时间为阶段。
2、确立状态及状态变量:totaltime时间内采摘sum种药品获得的最大价值。
3、决策:如果采摘第i种药品获得的价值大于不采摘的情况,最大价值等于采摘第i种药品获得的价值;反之,最大价值等于不采摘第i种药品获得的价值。
4、状态转移方程:
max【t】=max{value[i] + max[t-time[i]],max[t-1]}
5.将分析得到的结果实现在代码上。
#include <stdio.h>
int totalTime, medics;
int value[100];
int time[100];
int max[1001]; //全局变量默认的初值均为0,所以max【0】为该解的出口。
int main()
{
scanf("%d%d", &totalTime, &medics);
int i, t;
for (i=0; i<medics; i++)
{
scanf("%d%d", &time[i], &value[i]);
}
for (i=0; i<medics; i++)
{
for (t=totalTime; t>0; t--)
{
if (time[i] <= t)
{
if (value[i] + max[t-time[i]] > max[t]) //第i个的价值+不选第i个且用时为t-time[i-1]时最大价值
{
max[t] = value[i] + max[t-time[i]];
}
}
}
}
printf("%d\n", max[totalTime]);
return 0;
}
浙公网安备 33010602011771号