动态规划问题解决方法及示例

本文介绍了动态规划的概念,分析了动态规划与记忆搜索的区别,提供了优化动态规划问题的策略,通过一个换钱问题展示了动态规划的应用,并给出了LeetCode最长回文子串问题的三种解法,包括动态规划解决方案。
摘要由CSDN通过智能技术生成

什么是动态规划

动态规划是求解决策过程最优化的数学方法。如果一个问题可以分解成若干个子问题,并且子问题之间还有重叠的更小的子问题,就可以考虑用动态规划来解决这个问题。

应用动态规划之前要分析能否把大问题分解成小问题,分解后的每个小问题也存在最优解。如果将小问题的最优解组合起来能够得到整个问题的最优解,那么就可以使用动态规划解决问题。

可以应用动态规划求解的问题主要由四个特点:
1. 问题是求最优解
2. 整体问题的最优解依赖于各个子问题的最优解
3. 大问题分解成若干小问题,这些小问题之间还有相互重叠的更小的子问题
4. 从上往下分析问题,从下往上求解问题


分析

例:给定数组arr,arr中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求换钱有多少种方法。

思路及优化方法:

这里写图片描述

暴力搜索方法

arr={5、10、25、1},aim=1000

1、用0张5元的货币,让[10,25,1]组成剩下的1000,最终方法数记为res1
2、用1张5元的货币,让[10,25,1]组成剩下的995,最终方法数记为res2
3、用2张5元的货币,让[10,25,1]组成剩下的990,最终方法数记为res3
……
201、用200张5元的货币,让[10,25,1]组成剩下的0,最终方法数记为res201

最终结果为res1+res2+…+res201。

定义递归函数:int p1(arr, index, aim),返回用arr[index]至arr[N-1]的货币面值组成面值aim的方法数。

public class DynamicProgramming {
   

    public int coins1(int[] arr, int aim) {
        if (arr == null || arr.length == 0 || aim < 0) {
            return 0;
        }
        return process(arr, 0, aim);
    }

    /**
     * 即上述p1方法
     */
    public int process(int[] arr, int index, int aim) {
        int res = 0;
        if (arr.length == index) {
            return (aim == 0 ? 1 : 0);
        }
        for (int i = 0; arr[index] * i <= aim; i++) {
            // arr[index]选i张时,让剩下的货币组成aim-arr[index]*i面额的方法数,即res_i
            // 总的方法数即为res_0+res_1+...+res_(aim/arr[index])
            res += process(arr, index + 1, aim - arr[index] * i);
        }
        return res;
    }
}

优点:简单方便
缺点:重复计算导致多余的递归,最终导致效率低下

如果已经使用0张5元和1张10元的情况下,后续将求:process(arr, 2, 990);
但是如果已经使用了2张5元和0张十元时,也将要求:process(arr, 2, 990);
就会造成重复计算。

记忆搜索方法

思路:使用HashMap记录计算结果。

public class DynamicProgramming {
   

    /**
     * 二维数组map[i][j]的结果代表process(arr, i, j)的返回结果
     */
    private int[][] map;

    public int coins1(int[] arr, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值