动态规划常用的方面:
1.计数(count)
-有多少种方法走到右下角
-有多少种方法选出k个数使得和是sum
2.求最大最小值(max、min)
-从左上角走到右下角路径的最大数字和
-最长上升子序列长度
3.求存在性(bool)
-取石子游戏,先手是否必胜
-能不能选出sum为多少的k个数
从这道题目出发,总结动态规划的大致表现;
动态规划的思路:
1. 确定状态
-最后一步: K-1枚硬币(27-ak) + 最后一枚硬币(ak)【这里要假设是最优策略】
-子问题: 根据最后一步的假设得到子问题:K-1的最优策略
--------------------f(27) = min{f(27-2)+1,f(27-5)+1,f(27-7)+1}
2.转移方程
--------------------f(X) = min{f(X-2)+1,f(X-5)+1,f(X-7)+1}
3.初始条件和边界条件(这个是用于所有类型的编程设计)
-边界条件:f(1)拼不出来
-初始条件:不能算出来的如----f(0) = 0;
4.计算顺序
-过程量先于结果量算出来(这里就要选择从小到大)
int f(int X){
if(X==0)return 0;
int res = MAX_VALUE;//初始化为一个很大的数,如果无法按照2、5、7的路径凑完,返回他,不影响结果
if(X>=2){
res = min(f(X-2)+1,res);
}
if(X>=5){
res = min(f(X-5)+1,res);
}
if(X>=7){
res = min(f(X-7)+1,res);
}
return res;
}
缺陷(从大到小):
递归解法有很多节点多次运算(顺序不对),严重拖慢了速度。那么为了使计算量降低,使用从小到大的动态规划(JAVA)解决。