一般三类问题需要动态规划来处理
1、最大最小值
2、计数型,比如从A-B有多少种走法?但是不会把每周走法都罗列出来,很多时候我们会把罗列的个数的的题也当成动态规划,其实不是。
3、存在型,比如是否可以?是否能胜利等?
动态规划的4个步骤
举个列子:面值为2,5,7的硬币,组装27块钱,最少需要多少枚?
第一步:确定状态:什么是状态,简单讲就是要确定一个数组,数组的每个元素f[i]就是代表一个状态,而且这个状态的定义来源于整个问题划分成子问题后的意思:比如最少用多少枚硬币拼出x面值?那么测试f[x]就表示最少多少枚拼出x面值。确定状态需要依赖两个条件:
1.1、最后一步:最后一步也就是最后一枚硬币的面值:会有三种,2,5,7。三种情况f(27)=1+f(25) or f(27) = 1+f(22) or f(27) = 1+f(20)三种情况。而我们需要求的是最少的硬币个数:所以f(27)=min{1+f(25), 1+f(22),1+f(20},三个中最小的那个。确定最后一步的目的就是要通过最后一步来推到除问题的子问题。
1.2、子问题:如:最少用多少枚硬币拼出x面值
注意:其实动态规划表达式都可以用递归的方式计算出来。但是重复计算很多消耗CPU。
第二步:根据状态写出转移方程,意思就是写出通用表达式: 比如这里就是f(x)=min{f(x-2)+1,f(x-5)+1,f(x-7)+1};其实转移方程写出来,动态规划题就解决了一半。
第三步:确定方程的初始化条件和边界情况;初始条件一般都是0,1,2这样的,比如f(0)=? f(1)=? f(2)=?等等。而且初始条件的方程一般不能套用方程公式来计算而要用手动根据实际情况来算。
第四步:确定f(x)的计算顺序,是从大到小还是从小到达,这个取决于f(x)中x的依赖,比如x依赖与x-2,x-5,x-7所以只能先把小的算了才能算出大的x。因此是从小到大的顺序。