Java数据结构和算法——动态规划做题步骤详细总结

动态规划题目类型

1、计数:
有多少种方式走到右下角
有多少种方法选出k个数使得和为Sum
2、求最大最小值:
从左上角走到右下角路径的最大数字和
最长上升子序列长度
3、求存在性:
取石子游戏,先手是否必胜
能不能选出k个数使得和是Sum

动态规划解题步骤

1、确定状态
简单的说,就是解动态规划时需要开一个数组,数组的每个元素f[i]或者f[i][j]代表什么,类似解数学题中,xyz代表什么一样,具体分为下面两个步骤:
-------研究最优策略的最后一步
-------化为子问题
2、转移方程
根据子问题定义直接得到
3、初始条件和边界情况
初始条件一般都是a[0]、a[1]这种,多看看
边界条件主要是看数组的边界,数组越不越界
4、计算顺序
利用之前的计算结果

动态规划实例讲解

硬币问题

题目:有三种硬币,面值2.5.7,买一本书需要27元,如何用最少的硬币整好付清。

首先经过分析,这是一个求最大最小值问题,可用动态规划来求解。
1、确定状态
(1)最后一步
虽然我们不知道最优策略是什么,但是最优策略一定是k枚硬币a1,a2…ak加起来等于27
所以一定有一枚最后的硬币:ak
除掉这枚硬币,前面硬币的面值相加起来是27-ak,如图
在这里插入图片描述(2)化为子问题
所以就将原问题转化为了子问题:
原问题是最少用多少枚硬币拼出27(k枚)
子问题是最少用多少枚硬币拼出27-ak(k-1枚)

经过这两歩,得出状态:f[X]=最少用多少枚硬币拼出X

2、转移方程
设状态f[X]=最少用多少枚硬币拼出X
转移方程如下
在这里插入图片描述这时,可以用递归进行解题,大致如下
在这里插入图片描述但是有一个问题,递归是从上到下进行计算的,这样的话会产生大量的重复运算
在这里插入图片描述所以说,这不是一个好的解法,解决方法就是将计算结果保存下来,改变计算顺序,我们接着来看。

3、初始条件和边界情况
边界条件X-2,X-5,X-7小于0时,应该进行处理,这种情况其实就是拼不出来的情况,定义为正无穷

初始条件一般就是根据转移方程计算不出来的值,从转移方程变量为0或1来选,根据题目进行分析,这个题目的初始条件就是f[0]=1,代入公式的话应该f[0]为正无穷,显然错误,所以自己定义f[0]=0

4、计算顺序
这个题目应该是正序的,当我们计算到f[X]时,f[X-2],f[X-5],f[X-7]都已经得到结果了

在这里插入图片描述

在这里插入图片描述
代码:

	//A数组存储硬币金额,M代表商品价值
	public static int coinChange(int[] A, int M) {
   
        int[] f = new int[M + 1];
        f[0] = 0;

        for (int i = 1; i <= M; i++) {
   
            f[i] = Integer.MAX_VALUE;
            for (int j = 0; j < A.length; j++) {
   
            	//第一个条件是防止数组越界;第二个条件是防止MAX_VALUE+1越界
                if (i >= A[j] && f[i - A[j]] != Integer.MAX_VALUE) {
   
                    f[i] = Math.min(f[i], f[i - A[j]] + 1);
                }
            }
        }

        if (f[M] == Integer.MAX_VALUE) {
   
            f[M] = -1;
        }

        return f[M];
    }

机器人路径问题

题目:给定m行n列的网格,有一个机器人从左上角(0,0)出发,每一步可以向下或者向右走一步,问有多少种不同的方式走到右下角。

可用计数型动态规划来求解。

1、确定状态
(1)最后一步
聚焦机器人最后挪动的一歩,右下角坐标为(m-1,n-1),那么前一步机器人一定在(m-2,n-1)或者(m-1,n-2)

(2)子问题
轻易可得,机器人走到(m-1,n-1)的方式等于机器人走到(m-2,n-1)加上机器人走到(m-1,n-2)
原问题是有多少种方式从左上角走到(m-1,n-1)
子问题是有多少种方式从左上角走到(m-2,n-1)和(m-1,n-2)

经过这两歩,得出状态:f[i][j]为机器人有多少种方式从左上角走到(i,j&

  • 57
    点赞
  • 154
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值