【问题标题】:Modifying the Coin Change problem to keep track of what coin is used (not minimum number)修改硬币更换问题以跟踪使用的硬币(不是最小数量)
【发布时间】:2011-04-23 23:50:31
【问题描述】:

我编写了一个简单的硬币找零算法,该算法目前可以​​找到与购买某物所需的数量相匹配所需的最小硬币数量。我正在尝试对其进行修改,以便它跟踪要使用的每种面额的最小硬币数量,但我有点不足。所以,如果你将数字 6 传递给函数,它会说所需的最小硬币数量是 2(我已经记下来了),并且这样做的硬币组合是 4 美分硬币和 2分硬币。这是我的代码:

coins[5] = {1, 2, 4, 17, 28} //effectively kills any use of greedy algortihms
count[m];
int coins_needed_for(int m) {


//Initilization- fills array w/ -1s
for (int z = 1; z < m+1; z++) {
    count[z] = -1;      
}//for  

//fills in appropriate values
for (int j = 0; j < 5; j++) {   
    if (coins[j] < m)
        count[coins[j]] = 1;    
    else if (coins[j] == 1)
        return 1;   
    else
        break;
}//for  


//Execution 
for (int p = 1; p < m+1; p++) {     
    if (count[p] == -1) {           
        int min = 10000 //poor subsitute for infinity;

        for (int i = 0; i < 5; i++) {               

            if (coins[i] <= p) {                            
                if (count[p-coins[i]] + 1 < min) {
                    min = count[p-coins[i]] + 1;                            
                }                   
            }//if           
        count[p] = min;         
        }//for          
    }//if               
}//for  
return count[m];
}

我了解需要什么,但我不确定最好的方法是什么。我应该创建另一个数组吗?如果是,它必须是二维的吗?我可以创建一个结构来计算每个可能的 m 使用的每个硬币吗?我愿意接受任何建议。我不一定要寻找明确的答案,只是指点和有用的建议。为分配的问题寻求答案是错误的。谢谢!

【问题讨论】:

    标签: c++ dynamic-programming coin-change


    【解决方案1】:

    这是一个非常古老的问题,被称为“变革问题”。看看Wikipedia 对此有何评论。

    这是背包问题的一种形式,不是小问题。

    【讨论】:

      【解决方案2】:

      您可以使用除法和模数来更轻松地完成此操作。我举个例子。

      afterQuarterTotal = totalAmount % 25; numberOfQuarters = (totalAmount - afterQuarterTotal) / 25; afterDimeTotal = aftgerQuarterTotal % 10; numberOfDimes = (afterQuarterTotal - afterDimeTotal) / 10;

      等等……

      【讨论】:

      • 这仅在您可以使用贪心算法时才有效。使用 1728 获取硬币,你不能这样做。
      • 啊...我明白了。如果我使用标准的美国货币系统,那就太好了,但我不是。如果你输入一个像 34 这样的值,我的算法会正确地识别出你需要两个硬币才能做到这一点,但它会说它需要 1 28 美元、1 4 美元和 1 2 美元。回到绘图板!
      【解决方案3】:
      void recursive_program(int coins) 
      
      {
          int times;
          if (coins==0)                                                
                 return;
      
      if (coins>=28)                                                  
          {                                                             
          times=coins/28;
          cout<<times; 
          cout<<" * 28 for\t\t"<<times*28<<endl;
          return recursive_program(coins%28);
      }
      
      if (coins>=17)                                                
      {
          times=coins/17;
          cout<<times; 
          cout<<" * 17 for\t\t\t "<<times*17<<endl;
          return recursive_program(coins%17);
      }
      
      if (coins>=4)                                                 
      {
          times=coins/4;
          cout<<times;
          cout<<" * 4 for\t\t\t "<<times*4<<endl;
          return recursive_program(coins%4);
      }
      if (coins>=2)                                                 
      {
          times=coins/2;
          cout<<times;
          cout<<" * 2 for\t  "<<times*2<<endl;
          return recursive_program(coins%2);
      }
      
      if (coins>=1)                                                 
      {
          times=coins/1;
          cout<<times;
          cout<<" * 1 for\t\t\t\t  "<<times<<endl;
          coins=0;
          return recursive_program(coins);
      }
      }
      

      【讨论】:

      • 欢迎您,在这里,解释为什么要使用您的解决方案而不是如何使用是一个很好的做法。这将使您的答案更有价值,并帮助进一步的读者更好地理解您是如何做到的。我还建议您查看我们的常见问题解答:stackoverflow.com/faq。您还可以随时“编辑”您自己的帖子以添加更多信息或更正错误。 :)
      【解决方案4】:

      /* 硬币找零问题

      输入规范: 第一行预计金额 第二行期望硬币的数量 第三行包含按面额升序排列的硬币 假设硬币供应无限

      输出规格: 每个箱子首先显示最低面额的硬币,然后是下一个最高面额的硬币。 案例由行分隔 如果找不到总和,则打印 -1

      */

      #include<iostream>
      using namespace std;
      int *num,*coins,*maxC,n,amount,flag=0,stop=0;
      int sum()
      {
          int i=0,j;
          int sum=0;
          for(i=0;i<n;++i)
              for(j=0;j<num[i];++j)
                  sum+=coins[i];
          return sum;
      }
      void print()
      {
          int i,j;
          for(i=0;i<n;++i)
          {
              for(j=0;j<num[i];++j)
                  cout<<coins[i]<<" ";
          }
          cout<<endl;
      }
      void printNum()
      {
          int i;
          for(i=0;i<n;++i)
              cout<<num[i]<<" ";
          cout<<endl;
      }
      void nextIter()
      {
          int i,j;
          int stat=0;
          //printNum();   //Remove the comment if you want to see the values of num array in every iteration
          for(i=0;i<n;++i)
          {
              if(num[i]==0)
                  stat=1;
              else
              {
                  stat=0;
                  break;
              }
          }
          if(stat)
          {
              stop=1;
              return ;
          }
          for(i=n-1;i>=0;--i)
          {
              int dec=0;
              if(num[i]==0)
              {
                  dec=1;
                  num[i]=maxC[i];
              }
              else
              {
                  --num[i];
                  return ;
              }
          }
      }
      int find()
      {
          while(!stop)
          {
              if(amount==sum())
              {
                  flag=1;
                  print();
              }
              nextIter();
          }
      }
      int main()
      {
          int i;
          cout<<"\nEnter amount:";
          cin>>amount;
          cout<<"\nEnter number of coins:";
          cin>>n;
          coins=new int[n];
          maxC=new int[n];//contains maximum number of each denomination required
          num=new int[n];//contains current number of each denomination required
          for(i=0;i<n;++i)
          {
              cin>>coins[i];
              num[i]=maxC[i]=amount/coins[i];
          }
          find();
          if(!flag)
              cout<<"-1";
          cout<<endl;
          system("pause");
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2019-07-17
        • 2020-05-09
        • 2013-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        相关资源
        最近更新 更多