动态规划的一些思考

来源:互联网 发布:百度地图数据解析失败 编辑:程序博客网 时间:2024/05/16 06:39

 

一、初始化问题

如何初始化? 这个问题,其实就等同于:该对哪些子问题进行适当的标记。

拿01背包问题来说。

如果状态表示为将前i个物品放进容量为j的背包中。

①如果要求出背包装满情况下的最大值的话,那么在其最终的子问题中,只有将0个物品装到容量为0的背包中是可以供原问题是用的(如果可以将0个物体装到容量不为0的空间中的话,那这块空间就空了,不合题意)。为了避免依赖于这些我们认为不合法状态的解进入最终最优解的备选集合。我们将这些不合法的状态赋一个值,使依赖这个状态的解肯定不会被我们选中为最优解即可。通常的手段有:如果要求求最大值的话,那么将他们初始化为-∞;如果要求求最小值的话,那么将他们初始化为+∞。

 

②如果不要求背包装满的话,那么将“0装入容量不为0的空间”这样的状态是可以取的。所以我们把他们同样赋值为0。

 

二、最优解输出问题

我们是该遍历整个数组,还是取最终阶段(拿背包问题说,就是完成了全部物品的选择装入后)上的极端情况(满or空)呢?

这要看两个方面:

①能不能取到(像背包满这样的状态显然是不一定取得到的)。

②能取到的话,要看是不是最优值。像一些具有贪心性质的,我觉得是可以取某一极端状态的。比如,要求装最多的背包问题。一个更大的包,至少不会比原来少的包装得少;一个容量固定的背包装满东西后,剩余的容量当然是越少越好(如果能取到)。但是对于以下特殊的情况,就没有这样的贪心性质了。比如背包的容量是可增可减的,由于中间的变化情况是无法通过最终的某个状态体现出来的,你能说最终剩余容量最小的那个装了更多东西吗?不可以的。

 

三、状态如何描述

想一般的背包的问题我觉得怎么描述都好。但是对于容量可以增减,而且最大容量是有限制的,我觉得状态转移方程如果顺应(即不根据题目的意思进行逆推)题意的描述的话会显得简单很多,而且不容易出错。比如ZOJ 2972那题,它要求最大的force值不超过m。假设增加后的force为tmp,原来的体力为j,增加的量为f2。那我们应期望我们构造出的状态转移方程中出现这样的东西:tmp = j + f2; if(tmp > m) tmp = m; dp[i][tmp] = min(dp[i-1][j]+t3, dp[i][tmp]);这样显得比较自然。当然我们也可以枚举i阶段的j,然后寻找其i-1阶段中的子状态。我们就得这么写了:

 

这样就是逆推了,根据现在的状态去找出原来的状态。这样不仅写着麻烦,而且容易出错,你会不会写成这样呢?:

 

因为原来的值为正,增加的量也为正。那么增加后的值肯定比增加的量大嘛。~但是这样是错的!!因为最大容量是有限制的,不满足这样的加法性质。(得留意了)

 

原创粉丝点击