题目:

不同金额的货币,可以使用多张,凑成目标值的方法数

分析:

这里我写了两种,

第一种不能重复选,类似背包问题,选择当前金额和不选择当前金额分别传index+1和rest递归,返回值相加

第二种可以重复选,选择当前金额n张,不能超过rest,然后递归,将返回值累加起来

代码:

package mainimport("fmt"
)
//代表不同面值的数组,不重复选,凑成target的方法有几种,没有重复不用记忆化搜索
func process(list []int,index ,rest int) int{if rest==0{return 1}if index==len(list) && rest!=0{return 0}return process(list,index+1,rest-list[index])+process(list,index+1,rest)
}
//动态规划版
//当rest=0时的值全为1,即第一列dp[i][0]=1,
//list的index为n的时候,第一列为1,其余全为0,因为初始化为0,上面一行已经处理了第一列为1,所以不再处理
//每一个格子的值来自于i+1行的j列或dp[i][j]+dp[i][j-list[i]],同背包问题,因此要从左下倒叙填,返回右上的值
func process1(list []int,tar int) int{dp:=[][]int{}for i:=0;i<=len(list);i++{tmp:=[]int{}for j:=0;j<=tar;j++{tmp=append(tmp,0)}dp=append(dp,tmp)}for i :=0;i<=len(list);i++{dp[i][0]=1}for i:=len(list)-1;i>=0;i--{for j:=1;j<=tar;j++{if j-list[i]>=0{dp[i][j]=dp[i+1][j-list[i]]+dp[i+1][j]}else{//注意!!!!不满足条件的等于下面的格子dp[i][j]=dp[i+1][j]}}}return dp[0][tar]
}//不同面值的人民币,可以重复选n张,凑够target,有重复计算,可以应用记忆化搜索加快计算
func process2(list []int,index ,rest int,dp [][]int) int{if dp[index][rest]!=-1{return dp[index][rest]}if rest==0{dp[index][rest]=1return dp[index][rest]}if index==len(list) {if rest!=0{dp[index][rest]=0return dp[index][rest]}else{dp[index][rest]=1return dp[index][rest]}} result:=0for num:=0;num*list[index]<=rest;num++{result+=process2(list,index+1,rest-num*list[index],dp)}dp[index][rest]=resultreturn dp[index][rest]
}
//动态规划版
func process3(list []int,tar int)int{dp:=[][]int{}for i:=0;i<=len(list);i++{tmp:=[]int{}for j:=0;j<=tar;j++{tmp=append(tmp,0)}dp=append(dp,tmp)}for i :=0;i<=len(list);i++{dp[i][0]=1}//当前index依赖i+1,所以从左下开始倒叙填,行list元素,列rest//第一列dp[i][0]=1//每一个格子依赖i+1行的(rest-num*当前面值)格子的值for i:=len(list)-1;i>=0;i--{for j:=1;j<=tar;j++{result:=0// fmt.Printf("hreeeeeeeeeeeeeeeeeeee %v   %v  \n",i,j)if j>=list[i]{//先知当前rest大于等于当前面值才累加resultfor num:=0;num*list[i]<=tar;num++{// fmt.Printf("--------------------- %v   \n",j-num*list[i])if j-num*list[i]<0{//不越界break}result+=dp[i+1][j-num*list[i]]}}dp[i][j]=result//满足条件的值就是累加后的result,不满足条件就是0}}// for j:=0;j<=len(list);j++{//    fmt.Println(dp[j])// }return dp[0][tar]
}func main(){list:=[]int{70,100,1,4,9,21,33,2,50}tar:=105fmt.Println(process(list,0,tar))dp:=[][]int{}for i:=0;i<len(list);i++{tmp:=[]int{}for j:=0;j<=tar;j++{tmp=append(tmp,-1)}dp=append(dp,tmp)}process(list,0,tar)fmt.Println(process1(list,tar))list1:=[]int{5,10,20,50,100}fmt.Println(process2(list1,0,tar,dp))fmt.Println(process3(list1,tar))}

总结:
1 由暴力递归到动态规划,是一个空间换时间的过程
2 递归的coding过程,在于不断的尝试

算法48-不同面值的货币凑成目标值,掌握递归到动态规划相关推荐

  1. 数据结构与算法Java(二)——字符串、矩阵压缩、递归、动态规划

    不定期补充.修正.更新:欢迎大家讨论和指正 本文以数据结构(C语言版)第三版 李云清 杨庆红编著为主要参考资料,用Java来实现 数据结构与算法Java(一)--线性表 数据结构与算法Java(二)- ...

  2. 假设市面上有4种面值 硬币,20元、10元、5元、1元。输入一个钱数,能够使用最少的硬币凑成这个钱数

    假设市面上有4种面值 硬币,20元.10元.5元.1元.输入一个钱数,能够使用最少的硬币凑成这个钱数. 编程思想:先看看能取出来几个20元的,在看看剩下的钱能取出来几个10元的,以此类推再取五元和一元 ...

  3. 算法:换钱的最少货币数

    题目 给定数组arr,arr中所有的值都为正整数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数. 输入 输入包括两行,第一 ...

  4. 关于60枚一分两分五分硬币凑成一块钱的解决方法

    关于60枚一分两分五分硬币凑成一块钱的解决方法 一.强行三重for循环 #include<stdio.h> int main() {int a, b, c;for (a = 1; a &l ...

  5. 算法提高 邮票面值设计

    算法提高 邮票面值设计 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤13)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮 ...

  6. 算法提高 邮票面值设计 搜索 动态规划

    算法提高 邮票面值设计 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤13)种邮票的情况下(假定所有的邮票数量都足够),如何设 ...

  7. 322. 零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 你可以认为每

    零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 你可以认为每种硬币的数量 ...

  8. 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1

    /*** 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1.* 输入: coins = ...

  9. 关于 高斯算法计算某数可以被分割成连续自然数之和的组数 个人的一点拙见

    题目描述:基于高斯算法计算一个正整数可以被分割成多少组连续(包括自身)的自然数之和? 如: 3=3: 3=1+2: 5=5: 5=2+3: 6=6: 6=1+2+3: ....... 解题思路: 由S ...

  10. java 算法提高 邮票面值设计 蓝桥杯1046

    java 算法提高 邮票面值设计 蓝桥杯1046 算法提高 邮票面值设计 思路 代码 算法提高 邮票面值设计 Description 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤13) ...

最新文章

  1. Mockito 简明教程
  2. 中非谋定农业合作 -农业大健康·万祥军:提供农业解决方案
  3. ASP.NET Core + Angular 2 Template for Visual Studio
  4. excel实战应用案例100讲(十四)-Excel可直接分析的大数据语义层
  5. [转载]oracle常用经典SQL查询
  6. 【日语笔记】日常日语
  7. centos boot dvd版本_iPad版Photoshop来了,设计师可以躺着改稿了!!!
  8. SpringBoot 动态创建多定时任务
  9. Android 系统(212)---monkey实战–测试步骤、常用参数、常规monkey命令
  10. HDU 4296 building
  11. 1 1 2 2 3 ...java_java 接收一个键盘输入的整数,计算1-1/2!+1/3!-1/4!.....1/n!
  12. 安装MapGIS IGServer遇到的问题
  13. 卡尔曼滤波算法 C语言实现
  14. matlab获取图片上的字,Matlab读取图片代码
  15. 十大项目管理知识-进度管理
  16. 计算机课ppt插入图片,PPT中图片的巧妙切换 -电脑资料
  17. 大数据分析,主要运用了哪些关键技术?
  18. 小程序云数据库更新数组第n项
  19. Ubuntu12.04 Skype4.2 提示Skype can't connect,安装Skype4.3
  20. Keycloak实现手机验证码登录

热门文章

  1. 热烈祝贺智通人才连锁集团咸宁公司6月11日正式落户咸宁
  2. Windows下搭建MySQL Master Slave
  3. “Cookies因预料之外的输出被阻止。要获取帮助,请参见此文档或访问支持论坛。” 的解决方法
  4. 思科交换机配置试题_cisco交换机基本配置
  5. 项目跟踪、项目敏捷,UMS攸信构建了完整的任务工作流!
  6. 有没有xd了解杭州三维通信公司的,这家公司咋样?
  7. 计算机类试题库,银保监会考试题库:计算机类模拟试题练习(七)答案
  8. Java Web实战08-Spring、Spring MVC和Hibernate实现收银机系统(XML版本)
  9. 解决External Libraries里,没有Maven的依赖包问题
  10. 执行了getHibernateTemplate.save(user)后,控制台有hql语句输出,显示已经将数据存到数据库了,也没有抛出异常,但是去oracle数据库查的时候,压根就没有数据。。。。请问