当前位置: 首页 > 知识库问答 >
问题:

算法-在java硬币变化

怀晋
2023-03-14

我见过很多硬币更换问题,这个问题很独特。我尝试使用DP和递归,但我无法解决它。

这就是问题所在:

假设给定一个价格,X,其中X是美分,我有5种有限面额的硬币,1,5,10,20,50。我有不同数量的1、5、10、20、50分硬币。我想用最大数量的硬币来确定价格X。我该怎么做?(假设X总是可以用手头的硬币制作)

例如,如果价格X=52,并且

我有三枚一分硬币

我有四枚五分硬币

我有8枚10美分的硬币

我有6枚20美分的硬币

我有4个50美分的硬币

我想找出最大数量的硬币,以及可以用来定价的方法,在这种情况下:两枚1美分、四枚5美分、三枚10美分的硬币就是答案。

我想到了一个可用的算法,首先,我将每个硬币的数量和值放入arraylist,然后将数组列表传递到一个递归函数中,该函数将:

首先,扣除最小面额的价格,然后将1加到int max,其中max=当前使用的硬币数量。然后,递归调用价格=价格-最小面额的函数。

其次,我将通过取下一个最小的可用面额递归调用该函数。

我的基本情况是如果

1) price <0, return 0

2) if price ==0 and max=currMax,  return 1

3) if price>0, recursively call the 2 recursions listed above

编辑:添加代码。

我稍微修改了一下这个问题。

  1 import java.util.*;
  2 public class CountingChange{
  3     int max = 0; //maximum number of way to pay price
  4     int way = 0; //number of ways to make price
  5     private void run(){
  6         Scanner sc = new Scanner(System.in);
  7         int price = sc.nextInt();
  8         ArrayList<Integer> coins = new ArrayList<Integer>(); //kinds of coins. assumed to be 1,5,10,20,50
  9         for (int i = 0; i <5; i++){
 10             int coin = sc.nextInt();
 11             coins.add(i,coin);
 12         }
 13         int currMax = 0;
 14         counter(price,coins,currMax);
 15         System.out.println(String.valueOf(max) + " " + String.valueOf(way)); //output eg: 10 5, where 10 = max coins, 5 = ways
 16     }
 17     private void counter(int price,ArrayList<Integer> coins,int currMax){
 18         currMax += 1;
 19         if (coins.size()==0) return;             
              else if((coins.get(0)<0)||(price<0)){
 20             //check if AL is empty(no way to make change), smallest coin < 0(invalid), price<0(invalid)
 21             return;
 22         }
 23         else if (price==0){//successful change made
 24             if (currMax==max){ //check max coins used
 25                 way+=1;
 26             }
 27             else if (currMax>max){
 28                 way = 1;
 29                 max = currMax;
 30             }
 31         }
 32         else if(price>0){
 33             coins.set(0,coins.get(0)-1);//use smallest coin
 34             counter(price-coins.get(0),coins,currMax);
 35             coins.remove(0);//use other coins except smallest
 36             counter(price,coins,currMax);
 37         }
 38     }
 39     public static void main(String[] args){
 40         CountingChange myCountingChange = new CountingChange();
 41         myCountingChange.run();
 42     }
 43 }

我认为我的问题是,我是在扣除用于定价的硬币数量(而不是硬币的价值)。但我真的不知道如何使用合适的//什么样的数据结构来存储我的硬币及其价值。

共有1个答案

霍建柏
2023-03-14

您可以使用一个列表来跟踪在递归的每个点添加了哪些硬币。使用第二个列表跟踪当前最大解决方案。当你找到一个解决方案时,检查它是否有超过当前最大值的硬币。

下面是一些Java代码来说明:

public static void main(String[] args)
{
    int[] values = { 1, 5, 10, 20, 50 };
    int[] available = { 3, 4, 8, 6, 4 };
    int change = 52;
    List<Integer> maxCoins = new ArrayList<>();
    LinkedList<Integer> coins = new LinkedList<>();

    maxCoins(0, change, values, available, maxCoins, coins);

    System.out.println(maxCoins);
}

public static void maxCoins(int pos, int change, int[] values, int[] available, List<Integer> maxCoins, LinkedList<Integer> coins)
{
    if (change == 0)
    {
        if (maxCoins.isEmpty() || maxCoins.size() < coins.size())
        {
            maxCoins.clear();
            maxCoins.addAll(coins);
        }
    } 
    else if (change < 0)
    {
        return;
    }

    for (int i = pos; i < values.length && values[i] <= change; i++)
    {
        if (available[i] > 0)
        {
            available[i]--;
            coins.addLast(values[i]);
            maxCoins(i, change - values[i], values, available, maxCoins, coins);
            coins.removeLast();
            available[i]++;
        }
    }
}

输出:

[1, 1, 5, 5, 5, 5, 10, 10, 10]
 类似资料:
  • 首先,是的,这是我的硬件,我觉得很难,所以我真的很感激一些指导。 我需要证明对于当

  • 所以这是一个经典的问题,在一套硬币中找到一个假币,只使用一个称重天平。为了完整起见,这里有一个这样的问题的例子: 一个著名的例子有九个(或更少)物品,例如硬币(或球),它们的重量相同,除了一个,在这个例子中它比其他的更轻--一个假币(一个奇怪的球)。差别只有在秤上称重才能察觉--但只有硬币本身才能称重。仅用两个称重就能将假币隔离吗? 我们所处理的情况是,只有一枚硬币是假币,而且我们知道它是怎么回事

  • 我理解硬币兑换问题的贪婪算法(用尽可能少的硬币支付特定金额)是如何工作的——它总是选择面额最大但不超过剩余金额的硬币——并且它总是为特定的硬币组找到正确的解决方案。 但对于某些硬币集,贪婪算法会失败。例如,对于集合和总和30,贪婪算法首先选择25,剩下5,然后选择5个1,总共6枚硬币。但是,对于最少数量的硬币,解决方案是选择15枚硬币两次。 一组硬币必须满足什么条件,才能让贪婪算法找到所有总数的最

  • 我正在尝试构建一个交换算法,以交换与库存数量相同的硬币。我有一本字典,里面有两个面值的键值对 输入是要返回的值,例如2,80欧元。考虑到股票,我需要一个算法来计算返回资金的最佳方式 (最好的方法是库存硬币数量的标准差最低,这意味着所有面额的库存都是相同的),因此在这个例子中,我需要返还120欧元的硬币 我怎样才能计算出最好的数字,以返回每面额使用c算法,并保持股票相同的所有硬币? 其中map Va

  • 我在考虑换硬币时想到了以下问题,但我不知道一个有效的(伪多项式时间)算法来解决它。我想知道是否有任何伪多项式时间的解决方案,或者一些经典的文献,我遗漏了。 硬币变化问题有一个著名的伪多项式时间动态规划解决方案,它问以下问题: 取硬币仅此,将此硬币指定为具有值 取硬币仅此,将此硬币指定为具有值 取硬币和,将其赋值为具有值和,或和,它们分别被认为是相同的方式 取硬币,和,并将其赋值为具有值,和 我遇到

  • 我试图解决换硬币的问题,你用尽可能少的硬币来换钱。我尝试使用贪婪的方法——我的算法对硬币数组进行排序,从最大的硬币开始,并尽可能多地使用它,然后再移动到下一个硬币,将剩余的硬币分开。 这对初始测试用例有效: 硬币=[1,2,5],数量=11 但这次失败了: 硬币=[186,419,83,408],金额=6249 我不确定它为什么会失败,我仍在努力掌握贪婪的方法。非常感谢您的反馈!