一道简单的动态规划例题,硬币问题(coin Change lintcode上有)

就是说,假如给你若干枚不同面值的硬币,然后再给你一个值,问用最少的硬币数来加起来得到这个数字。
下面直接看题目(看了九章算法的课进行总结)
在这里插入图片描述
比如给的例1
我们可以知道,最后一枚硬币一定是1或2或5(没问题吧!)
在这里我们开一个数组f来表示方法数

那么我们的主要问题就是要求解出前面的f[11 - 1] or f[11 - 2] or f[11 - 5]中最小的那 个,变换为求解之前的子问题,因为最后一枚就是1个硬币。

所以f[11] = Min{ f[11 - 1] , f[11 - 2] , f[11 - 5] }。
初始条件f [0] = 0 (0元当然有0中可能。。。)其他的都设置为正无穷

我们从f [1] f [2] f [3]往后算,因为这样的话前面的都在之前算过了。比如说 f [11] = Min{ f[11 - 1] , f[11 - 2] , f[11 - 5] } ,在这里,f [10] f [9] f [6 ] 之前都算过了。

由于输入的值是一个数组以及最大的值M,在这里定义一个函数coinChange

首先计算一下数组的长度(就是那个输入的几个硬币的那个数字),比如example中的1 2 5 ,长度就是3,接着初始化f [0] = 0,接下来写两重循环,用来计算 f

public class A{
    public int coinChange(int[] A,int M)
    {
        int n = A.length;
        // 初始化一个数字,长度给M+1,因为我们下面写的话下标从1开始遍历
        int[] f = new int[M + 1];
        //初始条件f[0] = 0
        f[0] = 0;

        //两重循环
        for (int i = 1; i <= M; i ++){
            //首先全部设置为无穷大
            f[i] = Integer.MAX_VALUE;
            // 下面的循环用来取那个上文中提到的min
            for (int j = 0; j < n; j ++){
            //   硬币的大小要小于那个值  &&  min的条件   &&  不是无穷
                if (A[j] <= i && f[i - A[j]] + 1 < f[i] && f[i - A[j]] != Integer.MAX_VALUE){
                    // 更新f[i]的值,让它取到最小值
                    f[i] = f[i - A[j]] + 1;
                }
            }
        }
        // 到最后进行判断
        if (f[M] == Integer.MAX_VALUE){
            return -1;
        }else{
            return f[M];
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值