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

一种硬币交换变量的动态规划

章高爽
2023-03-14

我对解决硬币交换问题的一种变体感兴趣。回想一下硬币交换问题的正式定义:

给定一个值N,如果我们想改变N分,并且我们有无穷多的S={S1,S2,…,Sm}整值硬币,我们有多少种方法可以改变?硬币的顺序无关紧要。例如,对于N=4和S={1,2,3},有四种解决方案:{1,1,1},{1,1,2},{2,2},{1,3}。所以输出应该是4。对于N=10和S={2,5,3,6},有五个解:{2,2,2,2,2},{2,2,3,3},{2,2,6},{2,3,5}和{5,5}。所以输出应该是5。请参阅此处了解更多详细信息。

在这里,可以找到一个基于表格DP的解决方案。此解决方案基于以下递推关系:

count(S, m, n) = count(S, m - 1, n) + count(S, m, n - S[m - 1]);

与基本情况:

count(S, m, n < 0) = 0
count(S, m, n = 0) = 1
count(S, m <= 0, n >= 1) = 0

直观地说,这种递归关系将一个问题定义为两个子问题的解决方案:一个是我们丢弃硬币的问题,另一个是我们假设硬币一次使用一次的问题。

问:我如何修改这个递归关系来计算我们可以不考虑顺序和偶数个求和的求和方式的数量?例如,对于N=4和S={1,2,3},共有四个解(不考虑顺序):{1,1,1,1},{1,1,2},{2,2},{1,3},但其中只有3个求和数为偶数,即{1,1,1,1},{2,2},{1,3}。

先前的研究:首先,我认为我可以在丢弃硬币的情况下将请求的金额翻倍,并要求在我们将使用部分硬币的情况下,每枚硬币消费两次,即:

count(S, m, n) = count(S, m - 1, 2*n) + count(S, m, n - 2*S[m - 1]);

这适用于一些示例案例,但不起作用。有什么提示吗?

共有1个答案

冉绯辞
2023-03-14

您需要在递归中添加一个标志,它是到目前为止使用的求和数的奇偶校验。

使用求和键时,翻转标志(S(n-v[m],m,!奇偶校验))。

基本案例是:

n=0 parity=0 -> 1

n=0 parity=1 -> 0

n<0 or m<0 (array is 0-indexed) -> 0

下面是c中的递归函数。当然,你需要把它记下来,这样它才能产生更大的价值。

int S(int n,int m,bool parity)
{
    if (n==0)
    {
        if (parity==1)
            return 0;
        else 
            return 1;
    }
    if (m<0 || n<0)
        return 0;
    return S(n,m-1,parity)+S(n-v[m],m,!parity);
}
 类似资料:
  • 我正在练习动态规划。我的重点是硬币交换问题的以下变体: 让成为一组整数面值的常量。设为可通过中的硬币获得的正整数金额。考虑两个人<代码> A<代码>代码> B<代码>。我可以用多少种不同的方式将分为和,这样每个人都可以得到相同数量的硬币(不考虑每个人得到的实际金额)? 实例 每个人可以分成4种不同的方式: 人得到{2,2},人得到{1,1}。 人得到{2,1},人得到{2,1}。 人得到{1,1}

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

  • 但是我们不能这样做吗:(是给定的可用硬币的排序集,和是它的下标,是给定的最高价值硬币) 我写的东西有什么问题吗?虽然解决方案不是动态的,但不是更有效吗?

  • 在硬币系统C={c1,c2,…ck}中,应改变给定的数量x,以使每个硬币ci具有给定的重量wi。我们想计算可能变化的总重量。两种变化是不同的,如果他们包含在不同的顺序相同的硬币。 如何给出上述问题的动态规划递归?我知道最小硬币兑换问题的递归(即C(x)=min{C(x-C)1 for x

  • 这是我关于硬币更换问题的代码,用于打印一组硬币的总方式数和目标金额 我想知道是否有任何方法可以用相同的动态规划解决方案打印这些方法(借助内部构造的表或任何其他方法) 例如,如果一组硬币是[1,3,5],目标金额是6,那么总共有4种可能的方式。[1,1,1,1,1,1,1,],[1,1,1,3],[3,3],[1,5]]我希望这种方式的列表作为输出。

  • 我一直在使用动态规划研究硬币兑换问题。我尝试制作一个数组fin[],其中包含索引所需的最小硬币数,然后打印它。我已经写了一个代码,我认为应该给出正确的输出,但我不明白为什么它没有给出准确的答案。例如:对于输入:4 3 1 2 3(4是要更改的金额,3是可用硬币的类型,1 2 3是硬币值列表)输出应该是:0 1 1 2(因为我们有1,2,3作为可用硬币,需要0个硬币更改0,1个硬币更改1,1个硬币更