最近一直在做动态规划算法的专题训练,做了二十道题颇有感想,写出来和大家分享一下,欢迎广大ACMer,OIer,IOIer来交流~~~
对于动态规划各种算法书中提到的最多的一半就是分析阶段、找状态、写状态转移方程。的确这些能够证明对于一个问题,你的解题思路是否正确,但是如果要想能够完全解决一道动态规划问题,除了这些之外我感觉就是对于数据的初始化了,这就有些像”高考时父母说的不要输在起跑线上“,方向正确但是在起跑线上不能正确定位,那么最终也不会赢得一个好的结果。为此,我拿01背包为例,根据各种具体情况分析一下初始化的方法:
如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为0,所以初始时状态的值也就全部为0了。
但是通过做题我发现有的时候,有些题题目中没有说需要完全装满,但是给的数据却需要使用装满情况的初始化数据,例如hdu3496。
例如HDU3496中,如果使用滚动数组则状态转移方程为dp[j][k] = max(dp[j][k],dp[j-1][k-t[i]]+v[i]);
测试数组自身就可以记录上一个背包或者分组的结果进行状态结果的传递,不用人工处理。
如果使用二维数组,则状态转移方程为:f3496[i][j][k]=max3496(f3496[i-1][j][k],f3496[i-1][j-1][k-ti]+vi);本数组不能记录上一个分组的影响,所以需要人工添加转移的过程f3496[i][j][k]=max3496(f3496[i][j][k],f3496[i-1][j][k]);从而保证f3496[i][j][k](前i个物品取j个在资源限制k下去的最值)是能够涵盖前i-1、i-2、i-3...1的最优质,否者只是当前的最优值(有些类似贪心)。
当感觉状态转移方程没有出错的情况下WA了,一般会是初始化出错或者转移过程中是否需要考虑上一个状态或者分组的影响造成。例如(HDU3033、HDU3496)