前言
在这里向大家分享以下我的动态规划的思考方法,希望大家能够用上。
第一步
第一步就是先算好状态里面存的是什么,即 m a x 、 m i n 、 s u m max、min、sum max、min、sum等等。这一步只要把题目读懂了就一定能做出来。
第二步
第二部就是考虑如何存储状态,就是 f i , j , k , . . . f_{i,j,k,...} fi,j,k,...中的 i , j , k . . . i,j,k... i,j,k...。如果你确定了 d p dp dp一定是正解,那么你就可以把它暴力地设计出来。即不爆内存,而且能退出状态转移方程,且这样转移不超时,那么你就可以这样设计。
第三步
第三步就是动态规划中最难的一步:计算状态转移。其实这一步有两种方法:第一种,找规律,前提是你有时间写一个暴力程序;第二种,分类,可以把这个状态是从什么状态的情况得到的分成很多类,每一类中都可以用一个式子来计算,这样会方便的多,但是难度较大。
第四步
第四步就是考虑边界情况。考虑边界情况要做到两点:一、在算某个状态之前它的子问题已经计算了;二、哪些可以直接手算出答案,即值为 0 、 1 0、1 0、1等常数的状态。如果没有常数的状态也可以用方便计算的作为边界。其余的要设为一个极限值,如果是 m i n min min就设为极大值, m a x max max极小, s u m sum sum就可以设为 0 0 0等等。
第五步
第五步就是考虑答案是哪个状态。根据第一步设计的状态考虑答案包含了哪些状态,在这些状态中求最值或者和。
B计划
如果前面的方法没办法设计出 d p dp dp,你又十分确定 d p dp dp是正解,那你就可以写一个 d f s dfs dfs,保证 d f s dfs dfs传进来的参数一样得到的值一样,那么就可以套一个记忆化,然后再对其优化。如果怕记忆化常数高你还可以改成递推的形式。这个方法还是可以解决一大部分的题目的。