Java 从167.37美元开始计算不同的赚钱方式?
这是一个采访问题: 给定一个金额,比如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
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;iimport 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);
}
}