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

如何使用动态规划解决硬币行问题?

苍轶
2023-03-14

硬币行问题:有一行n枚硬币,其值为一些正整数C0,C2,Cn-1,不一定不同。目标是提取最大金额的货币,但受限制,不能提取初始行中相邻的两个硬币。

在下面的代码中,n是我的数组C的大小(或硬币的数量),这段代码返回了值[10, 2, 4, 6, 3, 9, 5]的正确结果(正确的结果是25)。但是当我为值[3,12,10]或[3, 12, 10, 2]运行相同的代码时,我得到了错误的结果。(该组值的结果应分别为13和14)。

请帮我修改代码。

int max(int a, int b) {
  if(a > b) return a;
  return b;
}

int coin_row(int[] C, int n) {
  if(n==1) return C[0];
  if(n==2) return max(C[0],C[1];

  int F[n], i;
  F[0] = 0; F[1] = C[0];

  for(i = 2;i < n;i++) {
    F[i] = max(C[i] + F[i-2], F[i-1]);
  }

  return F[n-1];
}

共有2个答案

习海
2023-03-14

您的算法是正确的,但在实现中存在一些错误。当循环从i=2开始时,跳过C[1]处的值。由于在F数组中包含0个硬币盒,因此F[n]的大小必须为n1。根据上述更正,我们得出:

int max(int a, int b) {
  if(a > b) return a;
  return b;
}

int coin_row(int* C, int n) {
  if(n==1) return C[0];
  if(n==2) return max(C[0],C[1]);

  int F[n+1], i;
  F[0] = 0; F[1] = C[0];

  for(i = 2 ; i <= n + 1 ; i++) {
    F[i] = max(C[i-1] + F[i-2], F[i-1]);
  }
  return F[n];
}
呼延景同
2023-03-14

所有数字都将是正数的说法让事情变得简单了一点。从这些信息中,我们可以确定我们永远不想跳过两个连续的数字。我们只需使用第一个数字计算可能的最佳序列,并将其与使用第二个数字可能的最佳序列进行比较。这是递归的理想选择。

int coin_row(int *C, int n) 
{
    int first_total;
    int second_total;

    if (n == 0) return 0;
    if (n == 1) return *C;
    if (n == 2) return max(*C, *(C+1));

    first_total = *C + coin_row(C+2, n-2);
    second_total = *(C+1) + coin_row(C+3, n-3);
    return(max(first_total, second_total));
}

通过将问题分解为一系列对,我们将列表视为一棵大的二叉树。在每一对中,您可以选择第一个或第二个数字。计算每个子树的总数并返回最大值。例如{10,2,4,6,3,9,5}的路径是:

          10                    2
          /\                   /\
         4  6                 6  3
        /\  /\               /\  /\
       3  9 9 5             9  5 5 -
 类似资料:
  • 这是我关于硬币更换问题的代码,用于打印一组硬币的总方式数和目标金额 我想知道是否有任何方法可以用相同的动态规划解决方案打印这些方法(借助内部构造的表或任何其他方法) 例如,如果一组硬币是[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个硬币更

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

  • 我在理解各种问题的动态规划解决方案方面存在问题,特别是硬币兑换问题: “给定一个值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,