动态规划解题思路

动态规划

一直以来都没有好好的了解动态规划问题,因为现在很多的笔试题中都会涉及动态规划的问题,所以通过学习动态规划来记录一下学习的笔记。

例题:

换硬币问题:

给出不同面额的硬币以及一个总金额. 写一个方法来计算给出的总金额可以换取的最少的硬币数量. 如果已有硬币的任意组合均无法与总金额面额相等, 那么返回 -1.

样例

输入:

[2, 5, 7]
27

输出:

 5

解释:

27 = 7 + 5 + 5 + 5 + 5
动态规划题目的特点

动态规划的解题步骤

1. 确定状态:

  • 最后一步
    在这里插入图片描述
    关键点1

    我们不关心前面的k-1枚硬币是怎么拼出27-ak的(可能有1种拼法,也可能有100种拼法),而且我们也不知道k和ak,但是我们知道前面拼出了27-ak。

    关键点2

    因为是最优策略,所以拼出的27-ak也是最少的,否则就不是最优策略。

  • 子问题
    通过对原问题的拆分,将原来的问题转换成了一个子问题,而且规模更小:27-ak。
    未来简化定义,我们可以设状态f(x)=最少用多少枚硬币拼出x

    因为需求的是最少的硬币,所以可以得出:
    f(27)=min{f(27-2)+1,f(27-5)+1,f(27-7)+1}

2. 转移方程
一般界动态规划都需要开一个数组:
设状态f[x]=最少用多少枚硬币拼出x;
对于任意的x:
f[27]=min{f[27-2]+1,f[27-5]+1,f[27-7]+1}

3. 初始条件和边界情况
在这里插入图片描述
对于初始条件:当使用转移方程计算不出来的时候,需要我们手动定义一个初始状态,例如f[0]=0,如果使用转移方程计算,得出结果应该是正无穷,然而f[0]是可以使用0枚硬币拼出来的,所以,应该有我们初始化指定。

  1. 计算顺序
    在这里插入图片描述
    代码:
public class Solution {
    /**
     * @param coins: a list of integer
     * @param amount: a total amount of money amount
     * @return: the fewest number of coins that you need to make up
     */
    public int coinChange(int[] coins, int amount) {
        // write your code here
        //开辟一个数组,大小为amount+1
        int[] f=new int[amount+1];
        //初始化
        f[0]=0;
        //计算顺序,从f[1],f[2].......f[27]
        for(int i=1;i<=amount;i++){
            //先将每个值设置为一个最大值,方便后面计算最少的方法
            f[i]=Integer.MAX_VALUE;
            //遍历所有硬币面额,使用转移方程计算
            for(int j=0;j<coins.length;j++){
                //边界条件(数组越界和当前一个不能够拼出)
                if(i>=coins[j] && f[i-coins[j]]!=Integer.MAX_VALUE){
                    //转移方程
                    f[i]=Math.min(f[i-coins[j]]+1,f[i]);   
                }
            }
        }
        //没有满足条件,直接返回-1
        if(f[amount]==Integer.MAX_VALUE){
            return -1;
        }
        //返回f[27]
        return f[amount];
    }
}

学习笔记来源于九章算法动态规划的视频。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值