使用背包解决硬币变化。参考:另一个背包 Hackerrank CodeAgon

Posted

技术标签:

【中文标题】使用背包解决硬币变化。参考:另一个背包 Hackerrank CodeAgon【英文标题】:Solving Coin Change using knapsack . Reference : Another Knapsack Hackerrank CodeAgon 【发布时间】:2015-09-04 07:11:03 【问题描述】:

这个问题相当简单直接。但是我不能完全使用 dp 背包样式来解决它。我对此有解决方案,但由于这里每种面额的硬币数量是有限的(在这个问题中它是),这就产生了一个问题。我想得到一个可以用来实现背包的 2d 重复。 我运行良好的实际解决方案如下:

#include<iostream> 
using namespace std ; 
int main ()
 int flag ;
  int N,i ; 
  int sum ; 
  int counter ; 
  while (cin >> N >>sum )
    
    counter = 0; 
    flag= 0 ;
    int count =0; 
    for( i = N ; i>=1;i--)
      count += i ;
      counter++;
      if (count >sum)
      count-=i ;
      counter -- ;  
      
      if(count == sum)
      flag = 1 ;
      break ; 
      
      
 if (flag==1)
 cout << counter<<"\n" ;
 else cout <<-1<<"\n" ;

return 0 ;

【问题讨论】:

【参考方案1】:

这个问题不需要动态规划解决方案,因为约束非常高。一个简单的贪婪方法就可以了。

算法的工作原理如下:

    如果从 1 到 n 的所有值的总和小于 m,则您无法支付 m 个硬币,因为即使在使用了所有 n 个硬币后,您还有剩余的钱要支付。 如果从 1 到 n 的所有值之和大于或等于 m,那么您肯定可以付款,因为您有足够的硬币。 由于您必须尽量减少要给您的硬币数量,因此您需要连续挑选具有最大值的硬币,直到您的 m 变为零,您只需要跟踪您挑选的硬币数量。

下面是实现上述算法的代码

#include <bits/stdc++.h>
using namespace std;
int main() 
    int n, m;
    cin >> n >> m;
    if (m > (n * (n + 1) / 2)) 
        //if sum of all coins form 1 to n is less than m
        cout << "-1";
     else 
        int cnt = 0;
        while (m != 0) 
            if (n >= m) 
                m = 0;
             else 
                m -= n;
                --n;
            
            ++cnt;
        
        cout << cnt;
    
    return 0;

【讨论】:

以上是关于使用背包解决硬币变化。参考:另一个背包 Hackerrank CodeAgon的主要内容,如果未能解决你的问题,请参考以下文章

找换硬币问题 与 0-1背包问题区别

POJ 1252 Euro Efficiency ( 完全背包变形 && 物品重量为负 )

背包算法变量

dp背包问题/01背包,完全背包,多重背包,/coin change算法求花硬币的种类数

[Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

HDU 2844 Coins (多重背包问题DP)