⚠️今天继续我们来探讨背包问题中的完全背包问题。完全背包:N个物品,容量为V,每个物品可以无限次使用,求达到V的最值。


???今日练习(一)零钱兑换(LeetCode-322)。给定一批硬币coins数组,每个硬币可以不限次数使用,求凑成总金额V至少需要多少个硬币。找不到输出-1。举例:

输入:[1,2,5] , 11输出:3。1+5+5=11输入:[2],3输出:-1;

?解法一:记忆化递归

?思路:

总体思路就是用coins中的每个数去凑总金额amount,用总金额减去使用过的数,直到amount小等于0退出递归。当amount==0,说明刚刚好凑齐。退出递归。使用一个map来保存递归中产生的零钱值,减少重复递归。

Mapmap = new HashMap<>();    public int coinChange(int[] coins, int amount) {        if(amount <= 0){            return 0;        }        return find_h(coins,amount);    }    private int find_h(int[] nums,int amount){        if(amount <0){            return -1;        }        if(amount == 0){            return 0;        }        if(map.containsKey(amount)){            return map.get(amount);        }        int count=Integer.MAX_VALUE;        for(int num:nums){            if(num > amount){                continue;            }            int solu=find_h(nums,amount-num);            if(solu>=0){                count = Math.min(count,solu+1);            }        }        if(count == Integer.MAX_VALUE){            count =-1;        }        map.put(amount,count);        return  map.get(amount);    }

?解法二:动态规划【自上而下】

?思路:

状态定义:F(S),凑齐总金额S,需要的最小硬币数。

状态转移方程:F(S) = F(S-coins[i]) + 1。

public int coinChange(int[] coins, int amount) {       if (amount < 1) return 0;    return coinChange_h(coins, amount,new int[amount+1]);}private int coinChange_h(int[] coins, int amount,int[] count) {    if (amount < 0) return -1;    if (amount == 0) return 0;    if (count[amount] != 0) return count[amount];    int min = Integer.MAX_VALUE;    for (int coin : coins) {        int res = coinChange_h(coins, amount - coin,count);        if (res >= 0 )            min = Math.min(1 + res,min);    }    count[amount] = min == Integer.MAX_VALUE ? -1:min;    return  count[amount];}

?解法三:动态规划【自下而上】

?思路:

状态定义:dp[j],凑齐总金额j,需要的最小硬币数。

状态转移方程:dp[i][j]= min(dp[i][j],dp[i](j-coins[i]) + 1)。凑齐总金额j需要的最小硬币数,当地i个硬币选或者不选两种情况。

public int coinChange_2(int[] coins, int amount) {    if (amount < 1) return 0;    int[] dp = new int[amount+1];    Arrays.fill(dp,amount+1);    //这儿解释下为啥默认填充amount+1,凑齐amount最多也就是面值为1的数总计用amount个,    // 所以最少个数一定是    dp[0]=0;    for(int j=1;j<=amount;j++){        for(int num:coins){            if(num <= j){                dp[j]=Math.min(dp[j],dp[j-num]+1);            }        }    }    return dp[amount]==amount+1?-1:dp[amount];}

复杂度分析

  • 时间复杂度:O(SN):这里S是总金额,N是提供的不同面额数,即数组长度。我们要计算O(S)个不同总金额,对每次的总金额需要N个面额来转移状态,一共需要O(SN)的时间复杂度。

  • 空间复杂度:O(S),我们使用了一个S+1的dp数组。


不积跬步,无以至千里。

文章有帮助的话,点个转发、在看呗

谢谢支持哟 (*^__^*)

END

?

编程实现背包的递归和非递归两种解法_算法动态规划(七)背包问题4相关推荐

  1. C#实现(递归和非递归)快速排序和简单排序

    C#实现(递归和非递归)快速排序和简单排序 本人因为最近工作用到了一些排序算法,就把几个简单的排序算法,想冒泡排序,选择排序,插入排序,奇偶排序和快速排序等整理了出来,代码用C#代码实现,并且通过了测 ...

  2. 二叉树创建及遍历算法(递归及非递归)(转)

    //二叉树处理头文件 //包括二叉树的结构定义,二叉树的创建,遍历算法(递归及非递归), /* 作者:成晓旭 时间:2001年10月7日(18:49:38-20:00:00) 内容:完成二叉树创建,二 ...

  3. 【恋上数据结构】递归(函数调用过程、斐波那契数列、上楼梯、汉诺塔、递归转非递归、尾调用)

    递归(Recursion) 什么是递归? 函数的调用过程(栈空间) 函数的递归调用过程 递归实例分析(1 + 2 + 3 + ... + 100 的和) 递归的基本思想.使用套路 斐波那契数列 fib ...

  4. 二叉树的先中后序递归和非递归遍历(数据结构作业)

    一.设计思想 我创建二叉树是用的先序创建,其中用'#'代表空节点. 1.递归先序遍历 (1)如果当前节点为空节点(用'#'代表空节点),结束当前函数 (2)打印当前节点 (2)递归当前节点的左子树 ( ...

  5. C++实现二叉树 前、中、后序遍历(递归与非递归)非递归实现过程最简洁版本

    本文并非我所写,是复制的该链接中的内容: 最近学习二叉树,想编程实现递归和非递归的实现方式: 递归的方式就不说了,因为大家的递归程序都一样:但是对于非递归的实现方式, 根据这几天的查阅资料已看到差不多 ...

  6. C++第七次作业(函数_递归与非递归_多文件)

    文章目录: 一:C++递归与非递归实现整数的阶乘 代码实现 运行结果 二:C++递归与非递归实现Fibonacci数列的计算:a0=1; a1=1; a2=a0+a1; a3=a1+a2; ..... ...

  7. python创建树结构、求深度_数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)...

    前面我们介绍了队列.堆栈.链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树.其他各种各样的树 ...

  8. 二叉树的几种递归和非递归式遍历:

    二叉树的几种递归和非递归式遍历: 1 #include <fstream> 2 #include <iostream> 3 4 using namespace std; 5 6 ...

  9. 全排列(含递归和非递归的解法)

    全排列在近几年各大网络公司的笔试中出现的比较频繁 首先来看看题目是如何要求的(百度迅雷校招笔试题). 用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, ...

最新文章

  1. 通过示例学习JavaScript闭包
  2. 基于ssh的ktv预定管理系统
  3. 写了一个开源的ASP.Net的系统信息探针(适用于MS.Net 1.x/2.0和Mono 1.0/2.0)
  4. python基础教程:两个list之间移动元素
  5. client-go workqueue demo
  6. Redhat Mongodb学习笔记
  7. 企业分布式微服务云SpringCloud SpringBoot mybatis (八)消息总线(Spring Cloud Bus)
  8. 北京网信金服PHP薪资_【企航金服工资|企航金服待遇怎么样】-看准网
  9. 心语家园系统维护工具箱v1.0
  10. kali 邮箱攻击_利用Kali linux制作钓鱼网站
  11. Java工作流引擎学习----JBPM(一)
  12. 如何通过vin及发动机号查询车辆出险、理赔、事故记录
  13. dwg格式转换成jpg图片
  14. ARCMAP里面关于地理投影方面的知识
  15. 阿里云ACP云计算对象存储OSS例题
  16. java orm全称_[Java-基础] 什么是ORM
  17. mysql 编程算法_十大编程算法助程序员走上高手之路
  18. Python老司机带你快速搞定日志分析工具
  19. Android 加壳与脱壳方式总结
  20. vue学习之关于element日历calendar组件中上月,今天,下月的显示

热门文章

  1. 前端学习(3268):js中this在类中的表现
  2. 前端学习(3258):js高级教程(2)
  3. [css] 写出你知道的CSS水平和垂直居中的方法
  4. 工作127:子向父亲传值
  5. 前端学习(2440):axios处理文章数据
  6. 前端学习(2335):angular之内置结构指令ngif
  7. 前端学习(2036)vue之电商管理系统电商系统之将本地的文件合并
  8. 前端学习(909):navigater对象
  9. 前端学习(753):js没有块级作用域
  10. shiro学习(14):springMVC结合shiro完成认证