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

动态编程硬币更换有限硬币

濮阳鸿卓
2023-03-14

动态规划变更问题(有限硬币)。我正在尝试创建一个以以下内容作为输入的程序

int coinValues[]; //e.g [coin1,coin2,coin3]
int coinLimit[]; //e.g [2 coin1 available,1 coin2 available,...]
int amount; //the amount we want change for.

输出:

int DynProg[]; //of size amount+1.

输出应该是大小为1的数组,其中每个单元格代表我们需要改变单元格索引量的最佳硬币数。

假设数组的单元格位于index: 5,内容为2。这意味着为了给出5(INDEX)的变化,您需要2(单元格的内容)硬币(最佳解决方案)。

基本上,我需要这个视频的第一个数组的输出(C[p])。这与有限硬币的大区别是完全相同的问题。链接到视频。

注意:看到视频了解,忽略视频的第2个数组,并记住我不需要组合,但DP数组,这样我就可以找到哪些硬币作为零钱。

非常感谢。

共有3个答案

阴元青
2023-03-14

这就是你要找的。假设:硬币价值按降序排列

public class CoinChangeLimitedCoins {

public static void main(String[] args) {
    int[] coins = { 5, 3, 2, 1 };
    int[] counts = { 2, 1, 2, 1 };
    int target = 9;
    int[] nums = combine(coins, counts);
    System.out.println(minCount(nums, target, 0, 0, 0));
}

private static int minCount(int[] nums, int target, int sum, int current, int count){
    if(current > nums.length) return -1;
    if(sum == target) return count;
    if(sum + nums[current] <= target){
        return minCount(nums, target, sum+nums[current], current+1, count+1);
    } else {
        return minCount(nums, target, sum, current+1, count);
    }
}

private static int[] combine(int[] coins, int[] counts) {
    int sum = 0;
    for (int count : counts) {
        sum += count;
    }
    int[] returnArray = new int[sum];
    int returnArrayIndex = 0;
    for (int i = 0; i < coins.length; i++) {
        int count = counts[i];
        while (count != 0) {
            returnArray[returnArrayIndex] = coins[i];
            returnArrayIndex++;
            count--;
        }
    }
    return returnArray;
}

}

秦俊友
2023-03-14

O(nk)我刚才写的一篇社论中的解决方案:

我们从运行在O(k*sum(c))中的基本DP解决方案开始。我们有一个dp数组,其中dp[i][j]存储了从第一个i面额到j面额的最少数量的硬币。我们有以下转换:dp[i][j]=min(dp[i-1][j-cnt*value[i]]cnt)从0到j/value[i]

为了将其优化为O(nk)解决方案,我们可以使用一个deque来记忆上一次迭代的最小值,并进行转换O(1)。基本思想是,如果我们想在某个数组中找到最后的m值中的最小值,我们可以保持一个递增的deque,该deque存储最小值的可能候选值。在每一步中,我们在将当前值推到后面的deque之前,在deque的末尾弹出大于当前值的值。由于当前值更偏右,并且小于我们弹出的值,因此我们可以确定它们永远不会是最小值。然后,我们弹出deque中的第一个元素,如果它超过m个元素。每个步骤的最小值现在只是deque中的第一个元素。

我们可以将类似的优化技巧应用于这个问题。对于每个硬币类型i,我们按此顺序计算dp数组的元素:对于每个可能的值j%value[i],我们按递增顺序处理j的值当除以value[i]时,会产生递增顺序的余数。现在,我们可以应用deque优化技巧,在恒定时间内从0到j/value[i]查找cnt的min(dp[i-1][j-cnt*value[i]]cnt)。

伪代码:

let n = number of coin denominations
let k = amount of change needed
let v[i] = value of the ith denomination, 1 indexed
let c[i] = maximum number of coins of the ith denomination, 1 indexed
let dp[i][j] = the fewest number of coins needed to sum to j using the first i coin denominations

for i from 1 to k:
    dp[0][i] = INF

for i from 1 to n:
    for rem from 0 to v[i] - 1:
        let d = empty double-ended-queue
        for j from 0 to (k - rem) / v[i]:
            let currval = rem + v[i] * j
            if dp[i - 1][currval] is not INF:
                while d is not empty and dp[i - 1][d.back() * v[i] + rem] + j - d.back() >= dp[i - 1][currval]:
                    d.pop_back()
                d.push_back(j)
            if d is not empty and j - d.front() > c[i]:
                d.pop_front()
            if d is empty:
                dp[i][currval] = INF
            else:
                dp[i][currval] = dp[i - 1][d.front() * v[i] + rem] + j - d.front()

燕智
2023-03-14

考虑下一个伪代码:

for every coin nominal v = coinValues[i]:
    loop coinLimit[i] times:
        starting with k=0 entry, check for non-zero C[k]:
            if C[k]+1 < C[k+v] then
                  replace C[k+v] with C[k]+1 and set S[k+v]=v

清楚了吗?

 类似资料:
  • 具体而言,问题是: 给定面额数组<代码>硬币[],每个硬币的限制数组<代码>限制[]和数量<代码>金额,返回所需的最小硬币数量,以获取<代码>金额,或者如果不可能,返回空值。另外,用溶液中使用的每个硬币的数量填充数组 这是我的解决方案: 但它一般不起作用。 我的问题是,例如,在这种情况下: 最佳解决方案是: 并且我的算法给出作为结果。换句话说,它失败了,每当在某种情况下,我将不得不使用比可能的更少

  • 问题:我很难找到达到特定金额所需的最低硬币数量。我很确定这是最简单的递归方式,使用动态编程方法,我基本上应该得到Math.min(“获取ACoin”、“离开ACoin”);不幸的是,我的代码不会终止,尽管我确实有在满足总和的条件下终止的if语句,硬币数组耗尽,或者如果总和结束。请查看下面的代码,让我知道我做错了什么,特别是为什么我的代码继续执行,直到它收到一个stackoverflow错误,尽管我

  • 我目前正在尝试用Python实现动态编程,但我不知道如何设置回溯部分,使其不会重复排列。例如,一个输入应该是(6,[1,5]),预期的输出应该是2,因为有两种可能的方式来排列1和5,使它们的总和等于6。这些组合是{1,1,1,1,1}和{1,5}但是我的程序目前的工作方式,它考虑了上面显示的组合和组合{5,1}。这导致输出为3,这不是我想要的。所以我的问题是“如何防止重复排列?”。我当前的代码如下

  • 问题:https://leetcode.com/problems/coin-change/ 解决方案:https://repl.it/@Stylebender/HatefulAliceBlueTransverse#index.js 我理解从“按钮式”构建dp阵列解决方案的一般概念流程,但我只是想知道关于第10行: dp[i]=数学。最小值(dp[i],1 dp[i-硬币[j]]; 当你选择当前的第

  • 我的硬币兑换动态编程实现在一些测试用例中失败,我很难找出原因: 问题陈述:给定一个数量和一个硬币列表,找出制造该数量所需的最小硬币数量。 例如: 目标金额:63 硬币列表:[1,5,10,21,25] 输出:[21,21,21] 小装饰品:https://trinket.io/python/43fcff035e

  • 我编写的代码使用动态规划解决了基本的硬币兑换问题,并给出了进行兑换所需的最小硬币数量。但是我想把每个硬币的数量存储在最小的数字里。 我试图做的是初始化数组,就像散列一样,只要找到,它就会增加的数量,即。但这并不是我想要的方式,因为它每次发现对应于时都会添加硬币。因此,在最终答案中,数字不是硬币的最终计数。 代码如下: