【动态规划法】硬币找零问题

简介: 【动态规划法】硬币找零问题

 1、题目如下:

【问题描述】

给定 n 种不同面值的硬币,分别记为 c[0], c[1], c[2], … c[n],假设每种硬币的数量是无限的。同时还有一个总金额 k,编写一个动态规划计算出最少需要几枚硬币凑出这个金额 k?

【样例输入】

12

1 2 5

【样例输出】

3

【样例说明】输入第一行为金额总数,第二行为硬币的不同面值;输出为需要的最少硬币数

2、算法思路

1、方法:动态规划法

2、dp[0]=0,从dp[1]开始,运算直至dp[MoneySum]。

3、动态转移方程:if(i-c[j]>=0) dp[i]=min(dp[i],dp[i-c[j]]+1);

注:输入数据的第二行以'\n'结尾,其中数据以空格间隔(详见代码)。

3、代码如下:

#include <bits/stdc++.h>
using namespace std;
#define N  10000
int MoneySum;//金额和 
int c[N];//硬币金额存储数组 
int dp[N];//所需最少硬币个数存储数组 
int main(){
  cin>>MoneySum;//输入金额和 
  int n=0;//记录硬币种类个数 
  for (int i= 0;i<=9; i++)
  {
    cin >> c[i];
    n++;//硬币种类个数加1 
    if (getchar()=='\n') break;//输入回车,则结束 
  }
  for(int i=0;i<=MoneySum;i++){//赋初值10000 
    dp[i]=N;
  }
  dp[0]=0;//记得将dp[0]初始化为0,当金额为0时,所需最少金币为0 
  for(int i=1;i<=MoneySum;i++){
    for(int j=0;j<n;j++){
      if(i-c[j]>=0) dp[i]=min(dp[i],dp[i-c[j]]+1);
      //cout<<"dp["<<i<<"]:"<<dp[i]<<endl;
    }
  }
  cout<<dp[MoneySum]<<endl;
  return 0;
}

image.gif


目录
相关文章
|
6月前
|
算法
【算法】贪心算法——柠檬水找零
【算法】贪心算法——柠檬水找零
|
9月前
|
算法 测试技术 C++
【状态压缩 容斥原理 组合数学】3116. 单面值组合的第 K 小金额
【状态压缩 容斥原理 组合数学】3116. 单面值组合的第 K 小金额
|
9月前
|
算法
【贪心算法】|860.柠檬水找零
【贪心算法】|860.柠檬水找零
|
算法
【递归算法题】硬币表示
【递归算法题】硬币表示
127 0
|
算法 Java Python
深入理解动态规划算法 | 凑硬币
深入理解动态规划算法 | 凑硬币
158 0
|
算法 Java
动态规划算法-凑硬币
动态规划算法-凑硬币
123 0
|
缓存 算法
钞票找零-贪心,动态规划算法
钞票找零-贪心,动态规划算法
139 1
|
算法 C语言
假币问题:有n枚硬币,其中有一枚是假币,已知假币的重量较轻。现只有一个天平,要求用尽量少的比较次数找出这枚假币。
(2)当n为奇数时,将前后两部分,即1…n,放在天平的两端,较轻的一端里有假币,继续在较轻的这部分硬币中用同样的方法找出假币;若两端重量相等,则中间的硬币,即第 (n+1)/2枚硬币是假币。n,放在天平的两端,较轻的一端里有假币,继续在较轻的这部分硬币中用同样的方法找出假币;假币问题:有n枚硬币,其中有一枚是假币,已知假币的重量较轻。:因为30位偶数,所以至少要被分一次,然后成为奇数之后,那个假币就是奇数的中位数,所以只需要2次。若输入的硬币数为30,则最少的比较次数为(2),最多的比价次数为(4)。
593 0
AcWing 656. 钞票和硬币
AcWing 656. 钞票和硬币
99 0
AcWing 656. 钞票和硬币