Java 从167.37美元开始计算不同的赚钱方式?

Java 从167.37美元开始计算不同的赚钱方式?,java,c,algorithm,data-structures,Java,C,Algorithm,Data Structures,这是一个采访问题: 给定一个金额,比如167.37美元,找到所有可能的方法,使用该货币中可用的面额来生成该金额的变化 任何能想到节省空间和时间的算法和支持代码的人,请分享 以下是我编写的代码(正在运行)。我正在尝试查找此功能的运行时间,非常感谢您的帮助 import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; public class

这是一个采访问题:

给定一个金额,比如167.37美元,找到所有可能的方法,使用该货币中可用的面额来生成该金额的变化

任何能想到节省空间和时间的算法和支持代码的人,请分享

以下是我编写的代码(正在运行)。我正在尝试查找此功能的运行时间,非常感谢您的帮助

    import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;


public class change_generation {

    /**
     * @param args
     */

    public static void generatechange(float amount,LinkedList<Float> denominations,HashMap<Float,Integer> useddenominations)
    {
        if(amount<0)
            return;
        if(amount==0)
        {
            Iterator<Float> it = useddenominations.keySet().iterator();
            while(it.hasNext())
            {
                Float val = it.next();
                System.out.println(val +" :: "+useddenominations.get(val));
            }

            System.out.println("**************************************");
            return;
        }

        for(Float denom : denominations)
        {

            if(amount-denom < 0)
                continue;

            if(useddenominations.get(denom)== null)
                useddenominations.put(denom, 0);

            useddenominations.put(denom, useddenominations.get(denom)+1);
            generatechange(amount-denom, denominations, useddenominations);
            useddenominations.put(denom, useddenominations.get(denom)-1);
        }

    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        float amount = 2.0f;
        float nikle=0.5f;
        float dollar=1.0f;
        float ddollar=2.0f;

        LinkedList<Float> denominations = new LinkedList<Float>();


        denominations.add(ddollar);
        denominations.add(dollar);
        denominations.add(nikle);

        HashMap<Float,Integer> useddenominations = new HashMap<Float,Integer>();
        generatechange(amount, denominations, useddenominations);
    }

}
import java.util.HashMap;
导入java.util.Iterator;
导入java.util.LinkedList;
导入java.util.Map;
公共阶级变革{
/**
*@param args
*/
public static void generatechange(浮动金额、LinkedList面额、HashMap UsedDeminations)
{
如果(金额)编辑

这是组合/子集问题的一个具体示例,请在此处回答

---我在下面保留我的答案(因为它对某人有用),但是,不可否认,它不是对这个问题的直接答案--

原始答案

最常见的解决方案是动态规划:

首先,你找到最简单的方法来改变1,然后你用这个解决方案来改变2,3,4,5,6等等……在每次迭代中,你“检查”你是否可以“向后”并减少你答案中的硬币数量。例如,在“4”之前你必须加上硬币。但是,一旦你到了“5”,你可以去掉所有的硬币,而你的解决方案只需要一枚硬币:镍币。但是,在9点之前,你必须再加一枚硬币,等等

然而,动态规划方法并不需要快速。


或者,你可以使用贪婪方法,不断地选择最大的硬币。这是非常快的,但并不总是给你一个最优的解决方案。然而,如果你的硬币是1 5 10和25,贪婪的工作非常完美,比线性规划方法快得多。

我会尝试在现实生活中对此进行建模

如果你是在TIN,你知道你必须找到167.37美元,你可能会首先考虑200美元作为“最简单的”招标,只是两张纸币。然后,如果我有,我可能会考虑170美元,即100美元,50美元和20美元(三注)。看看我要去哪里?< / P>
更正式地说,尽量用最少数量的纸币/硬币进行过度投标。这比全套可能性更容易列举。

不要使用浮动,即使是最微小的错误也会破坏您的算法

从最大的硬币/钞票到最小的硬币/钞票。对于每一个可能的金额,递归调用函数。当没有更多的硬币时,支付剩余的硬币并打印解决方案。这是伪C中的外观:

#define N 14

int coinValue[N]={20000,10000,5000,2000,1000,500,200,100,50,20,10,5,2,1};
int coinCount[N];

void f(int toSpend, int i)
{

    if(coinValue[i]>1)
    {
        for(coinCount[i]=0;coinCount[i]*coinValue[i]<=toSpend;coinCount[i]++)
        {
            f(toSpend-coinCount[i]*coinValue[i],i+1);
        }
    }
    else
    {
        coinCount[i]=toSpend;
        print(coinCount);
    }

}
#定义N 14
int coinValue[N]={200001000050002000500200100,50,20,10,5,2,1};
国际货币计数[N];
无效f(整数toSpend,整数i)
{
如果(coinValue[i]>1)
{
for(coinCount[i]=0;coinCount[i]*coincvalue[i]记忆化(类似)是您的朋友。C中的一个简单实现:

unsigned int findRes(int n)
{
   //Setup array, etc.

   //Only one way to make zero... no coins.
   results[0] = 1;

   for(i=0; i<number_of_coins; i++)
   {
       for(j=coins[i]; j<=n; j++)
       {
           results[j] += results[j - coins[i]];
       }
   }

   return results[n];
}
unsigned int findRes(int n)
{
//设置阵列等。
//只有一种方法可以制造零…没有硬币。
结果[0]=1;
对于(i=0;i
import java.util.HashMap;
导入java.util.Iterator;
导入java.util.LinkedList;
导入java.util.Map;
公共阶级变革{
静态int jj=1;
公共静态无效生成更改(浮动金额、LinkedList面额、,
HashMap使用(指定){

如果(数量)嗯,有趣-这是主要文章(math-y)-以及相关文章-你在这个问题上取得了多大进展?我建议你把你已经取得的成果公布出来,因为改进已经存在的东西更容易从零开始回答。@ford:我无法做到,因为时间不多,我只能说这可以递归地解决,每次减去t的值您决定使用的名称…重复:@Deltik:是的,但我看不出该线程中接受的答案..Nohsib希望生成所有可能的方式,而不是找到最佳方式。在问题的上下文中(找到生成更改的所有可能方式)什么是最佳解决方案?似乎这个问题只有一个正确的解决方案。问题是获得所有的可能性,而不是最佳的one@Banthar:当您回溯使用动态规划解决子集和问题时创建的表时,在其每个单元格中,您可能有多个将分叉路径的选项。这些选项是:(1)总和=此单元格的编号,(2)总和=来自其他单元格的其他编号,(3)总和=此单元格的编号+来自其他单元格的其他编号。您可以有(1)+(2)或(2)+(3)的组合。如果你从每个单元格中找到所有可能的路径,你就会有所有可能的解决方案。@Banthar:你知道我写的有什么问题吗/我遗漏了什么,或者这个解决方案只允许每枚硬币最多使用一次吗?
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

public class change_generation {

  static int jj=1;

  public static void generatechange(float amount,LinkedList<Float> denominations, 
                                  HashMap<Float,Integer> useddenominations) {
    if(amount<0)
        return;
    if(amount==0) {
        Iterator<Float> it = useddenominations.keySet().iterator();
        while(it.hasNext()) {
            Float val = it.next();
            System.out.println(val +" :: "+useddenominations.get(val));
        }
        System.out.println("**************************************");

        return;
    }

    for(Float denom : denominations) {
        if(amount-denom < 0)
            continue;
        if(useddenominations.get(denom)== null)
            useddenominations.put(denom, 0);

        useddenominations.put(denom, useddenominations.get(denom)+1);
        generatechange(amount-denom, denominations, useddenominations);
        useddenominations.put(denom, useddenominations.get(denom)-1);
    }
  }

  public static void main(String[] args) {
    float amount = 2.0f;
    float nikle=0.25f;
    float dollar=1.0f;
    float ddollar=2.0f;

    LinkedList<Float> denominations = new LinkedList<Float>();

    denominations.add(ddollar);
    denominations.add(dollar);
    denominations.add(nikle);

    HashMap<Float,Integer> useddenominations = new HashMap<Float,Integer>();
    generatechange(amount, denominations, useddenominations);
  }
}