动态规划在求解硬币问题中的应用(JAVA)--币制最大化、找零问题、硬币收集问题
动态规划:这种算法思想多用来求解最优化问题,因此这里存在一个最优化法则,法则指出最优化问题任一实例的最优解,都是由其子实例的最优解构成的。一般来说,自底向上的动态规划更容易设计,但是带有记忆功能的自顶向下的动态规划跟能高效的解决问题(尤其是针对重叠子的问题)。
1、币值最大化问题:给定一排n枚硬币,面值为正整数c1,c2,...,cn,面值可能相同,请问如何选取硬币,可以使得在其原始位置不相邻的条件下。所选币值总和最大。
思路:我们可以将问题划分为取最后一枚硬币和不取最后一枚硬币。根据不相邻这一条件,若取最后一枚硬币,则我们继续判断前n-2枚硬币中的币值总和最大问题;若不取最后一枚,则我们继续判断前n-1枚硬币中的币值总和最大问题。
由此得到递推方程如下,并且我们已知F(0) = 0,F(1) = c1,
Input:
6
5 1 2 10 6 2
Output:
17
import java.util.Scanner;public class Main {static int[] c = new int[10];static int[] f = new int[10];static Scanner in = new Scanner(System.in);public static void main(String[] args) {int n = in.nextInt();for (int i = 1; i <= n; i++) {c[i] = in.nextInt();}System.out.println(coinRow(n));}private static int coinRow(int n) {f[0] = 0;f[1] = c[1];for (int i = 2; i <= n; i++) {f[i] = Math.max(c[i] + f[i-2], f[i-1]);}return f[n];}
}
我们在这个过程中不仅得出了最大金额为17,我们在f[]中也可以求得前i枚硬币(1<=i<=6)的最大金额。时间复杂度和空间复杂度均为O(n)。
2、找零问题:假设我们需要找零的金额为n,至少需要多少面值为d1<d2<...<dm的硬币?其中d1 = 1,且每种面值的硬币无限制。
思路:我们可以理解获得n的途径为:在总金额为n-dj的一堆硬币中在找一枚面值为dj的硬币,其中j=1,2,...,m,且n>=dj。因此找到一个满足要求的dj使得F(n-dj) + 1最小的dj即可。由于1是常量,所以我们需要专注寻找一个最小的F(d-dj)。
由此得到的递推公式如下,且一直F(0) = 0
Input:
6
1 3 4
Output:
2
import java.util.Scanner;public class Main {static int[] c = new int[10];static int[] f = new int[10];static int sum;static Scanner in = new Scanner(System.in);public static void main(String[] args) {sum = in.nextInt();int n = in.nextInt();c[1] = 1;for (int i = 2; i <= n; i++) {c[i] = in.nextInt();}System.out.println(changeMaking(n));}private static int changeMaking(int n) {for (int i = 1; i <= sum; i++) {int temp = 99999999;int j = 1;while (j <= n && i >= c[j]) {temp = Math.min(f[i-c[j]], temp);j++;}f[i] = temp +1;}return f[sum];}
}
3、硬币收集问题:在n*m格模板中放有一些硬币,每格的硬币数目最多为一个。从左上方开始收集,尽可能收集多的硬币直到右下角对于每个单元格来说,只能取对应右边一格或者下边一格的硬币。试求出最大的硬币数及相应的路径。思路:我们假设F(i, j)为行走到(i, j)所能收集到的最大硬币数。单元格(i, j)可以经由上方(i-1, j)和左侧单元格(i, j-1)到达。单元格(i-1 ,j)对应的最大硬币数为F(i-1, j),(i, j-1)对应的最大硬币数为F(i, j - 1)。当然,第一行单元格上方没有单元格,第一列单元格左边没有单元格,即F(i-1, j) = 0,F(i, j-1) = 0,所以其递推公式为:
Input:
5 6
0 0 0 0 1 0
0 1 0 1 0 0
0 0 0 1 0 1
0 0 1 0 0 1
1 0 0 0 1 0
Output:
5
import java.util.Scanner;public class Main {static int[][] c = new int[10][10];static int[][] f = new int[10][10];static int sum, n, m;static Scanner in = new Scanner(System.in);public static void main(String[] args) {n = in.nextInt();m = in.nextInt();for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {c[i][j] = in.nextInt();}}f[1][1] = c[1][1];System.out.println(coinCollection());}private static int coinCollection() {/*** 左上角,初始位置* */f[1][1] = c[1][1];/*** 第一列只有上方来的* */for (int i = 2; i <= n; i++) {f[i][1] += f[i-1][1];}/*** 第一行只有左侧来的* */for (int j = 2; j <= m; j++) {f[1][j] += f[1][j-1];}for (int i = 2; i <= n; i++) {for (int j = 2; j <= m; j++) {f[i][j] = Math.max(f[i-1][j], f[i][j-1]) + c[i][j];}}return f[n][m];}
}
动态规划在求解硬币问题中的应用(JAVA)--币制最大化、找零问题、硬币收集问题相关推荐
- 动态规划在求解传递闭包问题中的应用(JAVA)--Warshell算法
动态规划在求解传递闭包问题中的应用: 传递闭包:对于n个顶点有向图来说,如果第i个顶点到第j个顶点之间存在一条有效的有向路径(即长度大于0的路径),那么T(i, j) = 1,否则T(i, j) = ...
- Python数据结构20:动态规划:找零兑换问题的动态规划解法并显示使用的硬币组合
在我们使用递归算法时,可能会出现规模庞大的重复计算,用一个中间表记录每个计算过的最优解法,就可以避免大量的重复计算.中间结果记录可以很好解决找零兑换问题.实际上,这种方法还不能称为动态规划,而是叫做& ...
- 硬币找零问题的动态规划实现
一,问题描述 给定一组硬币数,找出一组最少的硬币数,来找换零钱N. 比如,可用来找零的硬币为: 1.3.4 待找的钱数为 6.用两个面值为3的硬币找零,最少硬币数为2.而不是 4,1,1 因此,总 ...
- python 最小硬币数_Python之动态规划(最少硬币数找零)
完整代码: # 动态规划最少硬币数找零 def dpMakeChange(coinValueList, change, minCoins, coinsUsed): for cents in range ...
- Python 动态规划(DynamicProgramming)-硬币找零
动态规划(DynamicProgramming)-硬币找零 文章目录 动态规划(DynamicProgramming)-硬币找零 1.动态规划 a.什么是动态规划 b.适用对象 2.硬币找零-Codi ...
- 算法分析与设计:贪心算法实现最少硬币找钱问题(支付+找零共花费硬币数最少)
硬币找钱问题 Problem Description 设有六种不同面值的硬币,各硬币的面值分别为 5分,1角,2角,5角,1元,2元.现要用这些面值的硬币来购物和找钱.购物时可以使用的各面值的硬币个数 ...
- 基于单片机的自动化硬币分拣找零系统设计
博主福利:100G+电子设计学习资源包! http://mp.weixin.qq.com/mp/homepage?__biz=MzU3OTczMzk5Mg==&hid=7&sn=ad5 ...
- 动态规划在求解背包问题中的应用(JAVA)--回溯法、记忆化法
动态规划在求解背包问题中的应用 背包问题向来是动态规划的典型问题,给定n个重量为w1,w2,...,wn,价值为v1,v2,...,vn的物品和一个称重量为W的背包,求这些物品中最优价值的一个子集,且 ...
- 用动态规划算法求解最少硬币问题 c语言,动态规划算法求解硬币找零问题
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 看着这代码怎么这么熟悉. package 动态规划找零; import java.util.Scanner; public class Main { pu ...
最新文章
- 政策定价风控审批策略
- java发邮件_使用MATLAB自动发邮件
- 要锻炼二手交换的能力
- java web junit_如何使用junit测试javaweb工程
- java 新建 api 案列_Java利用webservice创建接口案例源码
- matlab ascii 异或,GPS数据包的ASCII异或校验和计算方法(VC++)
- 电脑硬盘分区合并_简单扩容电脑C盘,无需U盘重装系统
- 让Android虚拟手机快速启动
- 对数周期天线hfss建模_Ansoft HFSS 在设计对数周期天线时的仿真方法-HFSS教程
- 在线计算机带竖式,竖式计算器Scalar v4.2 采用竖式计算
- 解决Ubuntu、Deepin机箱前面板插耳机没声音
- 中国脑计划颠覆性创新之路二,欧美脑计划存在重大缺陷
- 牛刀小试imageROI
- QQ网页微信二维码登陆原理分析
- 德州仪器TM4C123GXL从入手到亮灯-开发环境配置
- Python 中的json模块dumps参数详解
- EditPlus安装Json格式化工具功能
- 按概率收敛与几乎处处收敛
- 青少年机器人等级考试四级考什么
- element UI-远程搜索(el-select)
热门文章
- verilog 生成块_如何高效的编写Verilog——终极版
- MySQL 修改和删除触发器
- Java在远程方法调用中运用反射机制
- Java Double类详解
- matlab电机标定,基于模型的电机标定及高精度电机建模
- android 手机号码显示加空格,Android实现输入手机号时自动添加空格
- linux 删除分区_详解linux系统架构--文件系统体系
- 144显示器只有60_你知道显示器60Hz和144Hz的刷新率差别有多大吗?你没有用过吗?...
- python生成1到100的列表_python列表生成式与列表生成器的使用
- python 按照当前日期创建文件