尝试为一般硬币更换问题编程一个DP解决方案,该解决方案还可以跟踪使用的硬币。到目前为止,我一直在努力给我所需的最低硬币数量,但不知道如何获得使用了哪些硬币以及使用了多少次。我尝试设置另一个表(布尔值),如果硬币被使用,但这似乎不能正常工作。有什么想法吗?
public static int minChange(int[] denom, int changeAmount)
{
int m = denom.length;
int n = changeAmount + 1;
int[][] table = new int[m][n];
boolean[][] used = new boolean[m][n];
for (int j = 0; j < n; j++)
table[m - 1][j] = j;
for (int i = 0; i < m; i++)
table[i][0] = 0;
for (int i = m-2; i >= 0; i--) //i denotes denominationIndex
{
for (int j = 1; j < n; j++) //j denotes current Amount
{
if (denom[i] > j)
{
table[i][j] = table[i+1][j];
//used[i][j] = false;
}
else
{
table[i][j] = Math.min(1 + table[i][j-denom[i]], table[i+1][j]);
/*Trying table for used coins
if (1 + table[i][j-denom[i]] < table[i+1][j])
used[i][j] = true;
else
used[i][j] = false;
*/
}
}
}
}
以下内容在Python中似乎有效:
def g( A, n ) :
#
if A == [] or n == 0 or min(A) > n :
return []
#
else :
#
min_len = float( "inf" )
min_seq = None
#
for i, a in enumerate( A ) :
if a <= n :
#
tmp = [ a ] + g( A[:i] + A[i+1:], n-a )
#
if len( tmp ) < min_len :
min_seq = tmp
min_len = len( min_seq )
#
return min_seq
#
for i in xrange(20) :
#
A = list( nr.randint( 1, 10, 5 ) )
print A, g( A[:-1], A[-1] )
public static int minimumNumberOfWays(int []deno, int amount){
int dp[] = new int[amount+1];
dp[0]=0;
int []prevCoin = new int[amount+1];
for(int j=1;j<=amount;j++){
dp[j]=Integer.MAX_VALUE;
for(int i=0;i<deno.length;i++){
if(deno[i]<=j && (1+dp[j-deno[i]] < dp[j]) ){
dp[j]=1+dp[j-deno[i]];
prevCoin[j]=deno[i];
}
}
}
int result = dp[amount];
List<Integer> coinsAdded = new ArrayList<Integer>();
for(int i=amount;i>=1;){
coinsAdded.add(prevCoin[i]);
int j=i;
i=amount-prevCoin[i];
amount = amount - prevCoin[j];
}
Integer [] coins = coinsAdded.toArray(new Integer[coinsAdded.size()]);
System.out.println( Arrays.toString(coins));
试试这个解决方案,它只使用了O(M)内存,复杂度为O(N*M):
public static int[] minChange(int[] denom, int changeAmount)
{
int n = denom.length;
int[] count = new int[changeAmount + 1];
int[] from = new int[changeAmount + 1];
count[0] = 1;
for (int i = 0 ; i < changeAmount; i++)
if (count[i] > 0)
for (int j = 0; j < n; j++)
{
int p = i + denom[j];
if (p <= changeAmount)
{
if (count[p] == 0 || count[p] > count[i] + 1)
{
count[p] = count[i] + 1;
from[p] = j;
}
}
}
// No solutions:
if (count[changeAmount] == 0)
return null;
// Build answer.
int[] result = new int[count[changeAmount] - 1];
int k = changeAmount;
while (k > 0)
{
result[count[k] - 2] = denom[from[k]];
k = k - denom[from[k]];
}
return result;
}
我有一个练习: 您将获得不同面额的硬币和总金额。请编写一个函数来计算您需要的最少数量的硬币,以弥补该金额。如果硬币的任何组合都无法弥补该金额,请返回-1 例1: 我还谷歌了一个这样的解决方案: 我知道它是关于DP的,但是,我对它很困惑,比如,的含义是什么,为什么要添加,为什么要添加,为什么要添加1? 有人能用简单的英语指出出路吗?
硬币兑换是一个非常普遍的问题,它问你有多少种方法可以使用硬币(C[0],C[1]…C[K-1])得到N美分的总和。DP解决方案是使用方法s(N,K)=s(N,K-1)s(N-C[K-1],K),其中s(N,K)是与前K个硬币(按升序排序)求和N的方法数量。这意味着使用前K个硬币获得N美分的方式数量是不使用第K个硬币获得相同金额的方式数量加上获得N-第K个硬币的方式数量的总和。我真的不明白你怎么会想
我在理解动态规划中的硬币兑换问题时遇到了一个小问题。简单地说,我必须用最少数量的硬币来兑换一笔钱。 我有n种面值为1=v1的硬币
给定一个值N,如果我们想换N美分,并且我们有无限量的S={S1,S2,…,Sm}值的硬币,我们可以用多少种方式来换?硬币的顺序无关紧要。 例如,对于N=4和S={1,2,3},有四种解:{1,1,1,1},{1,1,2},{2,2},{1,3}。所以输出应该是4。对于N=10和S={2,5,3,6},有五个解:{2,2,2,2},{2,2,3,3},{2,2,6},{2,3,5}和{5,5}。所以
问题:https://leetcode.com/problems/coin-change/ 解决方案:https://repl.it/@Stylebender/HatefulAliceBlueTransverse#index.js 我理解从“按钮式”构建dp阵列解决方案的一般概念流程,但我只是想知道关于第10行: dp[i]=数学。最小值(dp[i],1 dp[i-硬币[j]]; 当你选择当前的第
动态规划变更问题(有限硬币)。我正在尝试创建一个以以下内容作为输入的程序: 输出: 输出应该是大小为1的数组,其中每个单元格代表我们需要改变单元格索引量的最佳硬币数。 假设数组的单元格位于index: 5,内容为2。这意味着为了给出5(INDEX)的变化,您需要2(单元格的内容)硬币(最佳解决方案)。 基本上,我需要这个视频的第一个数组的输出(C[p])。这与有限硬币的大区别是完全相同的问题。链接