最少硬币个数

问题描述:假设有 1 元,3 元,5 元的硬币若干(无限),现在需要凑出 11 元,问如何组合才能使硬币的数量最少?
解题思路:
1、动态规划
假设总价值为i,先假设一个函数d(i)来表示需要凑出i的总价值需要的最少硬币数量。
当i=0时,我们不需要拼凑硬币,因为总价值为0
当i=1时,因为有1元我们需要1个1元,所以d(1)=1。
当i=2时,因为没有2元,所以我们需要2个1元,d(2)=2.
当i=3时,因为有3元,所以我们需要1个3元就好了,d(3)=1.
….
可以看出,除了第一步以外,往后的结果都建立在它之前得到的某一步的最优解上再加上1个硬币得出。比如d(1)=d(0)+1,d(2)=d(1)+1,d(3)=d(0)+1.
所以d(i) = d(j)+1 j < i

(1)假设最后加上的是 1 元硬币,那 d(i) = d(j) + 1 = d(i - 1) + 1。
(2)假设最后加上的是 3 元硬币,那 d(i) = d(j) + 1 = d(i - 3) + 1。
(3)假设最后加上的是 5 元硬币,那 d(i) = d(j) + 1 = d(i - 5) + 1。
需要凑18元时,我们首先找18-1=17,18-3=15,18-5,=13;再找17-1……。这样递归解决子问题

//money需要凑的钱  
//coin可用的硬币  
//硬币种类  
void FindMin(int money,int *coin, int n,int *&Num,int *&Values)
{
    Num[
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java代码实现: ```java import java.util.Scanner; public class Main { static int[] coins = {200, 100, 50, 20, 10, 5}; // 硬币面值(单位为分) static int[] count = new int[6]; // 硬币数量 public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); // 组数 while (n-- > 0) { for (int i = 0; i < 6; i++) { count[i] = sc.nextInt(); } double money = sc.nextDouble(); // 付款金额(单位为) int target = (int) (money * 100); // 付款金额(单位为分) int[] dp = new int[target + 1]; // dp[i]表示付款金额为i分时使用的最少硬币个数 for (int i = 1; i <= target; i++) { dp[i] = Integer.MAX_VALUE; // 初始化为最大值 for (int j = 0; j < 6; j++) { if (i >= coins[j] && count[j] > 0) { dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); // 转移方程 } } } if (dp[target] == Integer.MAX_VALUE) { System.out.println("impossible"); } else { System.out.println(dp[target]); } } } } ``` 算法思路: 使用动态规划算法,设dp[i]表示付款金额为i分时使用的最少硬币个数。则有转移方程: $$dp[i] = \min(dp[i], dp[i - coins[j]] + 1)$$ 其中coins[j]表示第j种面值的硬币,dp[i-coins[j]]表示付款金额为i-coins[j]分时使用的最少硬币个数。因此,只需要遍历每种面值的硬币,如果当前面值的硬币可以使用(即i大于等于当前面值的硬币,且当前面值的硬币数量大于0),则更新dp[i]的值。 最后判断dp[target]的值是否为Integer.MAX_VALUE,如果是,则输出"impossible";否则,输出dp[target]的值即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值