动态规划题的特点
-
计数
有多少种方式走到右下角
有多少种方式选出k个数使得和是sum
-
求最大最小值
从左上角走到右下角路径的最大数字和
最长上升子序列长度
-
求存在性
取石子游戏,先手是否必胜
能不能选出k个数使得和是sum
动态规划组成部分一:确定状态
状态在动态规划中的作用属于定海神针
简单的说,解动态规划的时候需要开一个数组,数组的每个元素f[i],或f[i] [j]代表什么?
类似于解数学题中,x,y,z代表什么
确定状态需要两个意识:
1.最后一步
2.子问题
动态规划组成二:转移方程
例题:一本书27元,有许多两元,五元,七元硬币,请用最少的钱数拼出27元
设状态F[X]=最少用多少枚硬币拼出X
对于任意X
F[X]=min{F[x-2]+1,F[x-5]+1,F[x-7]+1}
F[x-2]+1:拼出X-2所需最少的硬币数,加上最后一枚硬币2,
其它两个一样
动态规划组成部分三:初始条件和边界情况
F[X]=min{F[x-2]+1,F[x-5]+1,F[x-7]+1}
两个问题: X-2,X-5 or X-7小于0怎么办?
如果不能拼出Y,就定义F[Y]=正无穷
例如F[-1]=F[-2]=…=正无穷
所以F[1]=min{F[-1]+1,F[-4]+1,F[-6]+1}表示正无穷,拼不出1
初始条件:F[0]=0
动态规划组成部分四:计算顺序
- 拼出X所需要的最少硬币数:F[X]=min{F[x-2]+1,F[x-5]+1,F[x-7]+1}
- 初始条件:F[0]=0;
- 然后计算F[1],f[2]…F[27];
- 当我们计算到F[X]时,F[X-2],F[X-5],F[X-7]都已经计算出来了
动态规划是从小而上思考,递归是从上而下思考
return (res[res.length >> 1] + res[(res.length >> 1) - 1]) / 2.0;