文章目录

  • 1. 问题描述
  • 2. 问题分析
    • 2.1 回溯法求解
    • 2.2 DP状态转移方程法
    • 2.3 DP状态转移表法

1. 问题描述

找零问题,在贪心算法讲过。但是贪心不一定能得出最优解。假设有几种不同币值的硬币v1,v2,.……vn(单位是元)。如果要支付w元,求最少需要多少个硬币。比如,有3种不同的硬币,1元、3元、5元,我们要支付9元,最少需要3个硬币(3个3元的硬币)。

2. 问题分析

2.1 回溯法求解

/*** @description: 找零钱,需要张数最少,回溯法* @author: michael ming* @date: 2019/7/20 22:50* @modified by:*/
#include <iostream>
#define N 3
int rmb[N] = {1,9,10};//钞票面额
int amount[N];
int minAmount[N];
using namespace std;
void exchange(const int &targetMoney, int curMoney, int &minPiece, int piece)
{if(curMoney > targetMoney)//超过目标,返回return;if(curMoney == targetMoney)//达到目标金额{if(piece < minPiece){minPiece = piece;//更新最小张数for(int i = 0; i < N; ++i)minAmount[i] = amount[i];//获取每张钞票的张数}return;}for(int i = 0; i < N; ++i){//递归调用,拿取每张面额的钞票amount[i]++;exchange(targetMoney,curMoney+rmb[i],minPiece,piece+1);amount[i]--;//恢复上次的状态}
}
int main()
{int minPiece = 65535, piece = 0,targetMoney = 18, curMoney = 0;exchange(targetMoney,curMoney,minPiece,piece);cout << "凑成" << targetMoney << "元,最少需要:" << minPiece << "张(枚)。" << endl;int i = 0;while(i < N){if(minAmount[i] != 0)cout << minAmount[i] << "个" << rmb[i] << " ";i++;}cout << endl;cout << "----------------------" << endl;
}

2.2 DP状态转移方程法

由于上面的钞票面额可能不止3种,递归树是多叉树,所以状态转移表法画起回溯的递归图比较麻烦,我们采用状态转移方程法。

状态转移方程如下:

minPiece(targetMoney) = 1 + min{minPiece(targetMoney-rmb[0]), ... , minPiece(targetMoney-rmb[N-1])}

targetMoney = 18;//目标金额
rmb[N] = {1,9,10};//钞票面额
对于题目的情况,代入具体数值,状态转移方程如下

minPiece(18) = 1 + min{minPiece(18-1), minPiece(18-9) , minPiece(18-10)}= 1 + min{minPiece(17),minPiece(9),minPiece(8)}

DP(递归+备忘录)代码如下:

/*** @description: 找零钱,需要张数最少* @author: michael ming* @date: 2019/7/20 18:35* @modified by: */
#include <iostream>
#include <algorithm>
#include <memory.h>#define N 3
const int targetMoney = 18;//目标金额
int rmb[N] = {1,9,10};//钞票面额
int mem[targetMoney+1];//备忘录,存放最小张数
using namespace std;
int minP(int Money)
{if(Money < 0)//超过目标,返回很大的张数,表示不可能凑成return 65535;if(Money == 0)//达到目标金额return 0;if(mem[Money] > 0)//计算过了,直接读取备忘录return mem[Money];int minAmount[N];memset(minAmount,65535,N*sizeof(int));for(int i = 0; i < N; ++i){//递归调用,拿取每张面额的钞票minAmount[i] = minP(Money-rmb[i]);}sort(minAmount,minAmount+N);mem[Money] = minAmount[0]+1;//记录最小的张数return mem[Money];
}
int main()
{cout << "凑成" << targetMoney << "元,最少需要:"<< minP(targetMoney) << "张(枚)。" << endl;//如何打印出选取钞票的面额和张数???
}

2.3 DP状态转移表法

/*** @description: 找零钱,需要张数最少,dp状态表法* @author: michael ming* @date: 2019/7/21 20:01* @modified by: */
#include <iostream>
#include <algorithm>
#include <memory.h>#define N 3
const int targetMoney = 18;//目标金额
int rmb[N] = {1,9,10};//钞票面额,从小到大
using namespace std;
void exchange(int Money)
{int maxPiece = targetMoney/rmb[0];//最大张数int i, j, k;int (*states)[targetMoney+1] = new int [maxPiece][targetMoney+1];//memset(states,65535,maxPiece*(targetMoney+1)*sizeof(int));//上面错误!!!memset一般只付0或极大值for(i = 0; i < maxPiece; ++i)for(j = 0; j <= targetMoney; ++j)states[i][j] = 65535;//初始化for(k = 0, j = 0; j <= targetMoney; ++j){if(k < N && j == rmb[k]){//初始化第一行数据states[0][j] = 1;//一张rmbk++;}}for(i = 1; i < maxPiece; ++i)//动态规划{for(j = 0; j <= targetMoney; ++j)//上面一行的数据考下来states[i][j] = states[i-1][j];for(j = 0; j <= targetMoney; ++j){if(states[i-1][j] != 65535){for(k = 0; k < N; ++k){if(j+rmb[k] <= targetMoney && states[i-1][j+rmb[k]] > states[i-1][j]+1)states[i][j+rmb[k]] = states[i-1][j]+1;}}}}cout << "凑成" << targetMoney << "元,最少需要:"<< states[maxPiece-1][targetMoney] << "张(枚)。" << endl;//------------打印选择的信息---------------------------for(i = maxPiece-1; i >= 1 && states[i][targetMoney] == states[i-1][targetMoney]; --i);//此时i等于最早出现的答案处的行for(j = targetMoney; j > 0; ){if(i != 0){for(k = 0; k < N; ++k){if(states[i-1][j-rmb[k]] == states[i][j]-1){cout << "1张" << rmb[k] << " ";j = j-rmb[k];i--;break;}}}else{cout << "1张" << j << " ";break;}}delete [] states;//释放资源
}
int main()
{exchange(targetMoney);return 0;
}


动态规划应用--找零钱相关推荐

  1. 【README3】动态规划之“找零钱”说明最优子结构怎么解决

    接上文:[README2]动态规划之斐波那契数列说明重叠子问题如何解决 文章目录 找零钱问题说明最优子结构 (1)何为最优子结构 (2)状态转移方程 暴力解法 (3)备忘录解决重叠子问题 (4)迭代解 ...

  2. 【恋上数据结构】动态规划(找零钱、最大连续子序列和、最长上升子序列、最长公共子序列、最长公共子串、0-1背包)

    动态规划(Dynamic Programming) 练习1:找零钱 找零钱 - 暴力递归 找零钱 - 记忆化搜索 找零钱 - 递推 思考题:输出找零钱的具体方案(具体是用了哪些面值的硬币) 找零钱 - ...

  3. java 动态规划找零钱_动态规划之找零钱问题

    找零钱是一个经典的动态规划问题.这种问题,我建议,首先学会暴力解法,然后从暴力解法中优化出动态规划的解法,这样,更能体会动态规划的魅力. 问题描述 有n种不同币值的硬币,硬币数量无限.给定一个数量T, ...

  4. java 动态规划找零钱_初探动态规划——LeetCode找零钱问题

    1.简介: 在leetcode上刷题的时候,遇到了一道找零钱的动态规划题,后台测试用例很变态,必须把算法优化的很好才能通过.也借此机会好好的研究了一下动态规划.在下小白一个,大神轻喷. 2.题目如下: ...

  5. 动态规划解决找零钱问题

    动态规划算法 通常用于求解具有某种最优性质的问题.动态规划算法与分治法类似,其基本思想都是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动 ...

  6. $动态规划系列(2)——找零钱问题

    refer:http://interactivepython.org/courselib/static/pythonds/index.html 1. 问题描述 Tom在自动售货机上买了一瓶饮料,售价3 ...

  7. 【数据结构】动态规划——找零钱问题解析(含c++和python代码)

    一个具体的找零钱问题: 参考:程序员面试再也不怕动态规划了,看动画,学DP,找零钱 (LeetCode 322) 硬币面值:1,2,5,7,10 找零金额:14 step1:定义长度为15的dp数组 ...

  8. 动态规划算法思想解决找零钱问题

    前言 关于找零钱问题,网上已经有很多相关的资料以及优秀的文章博客等.这里写这篇博客的初衷很简单,就是为了方便自己,回过头来捡起这个知识能快一点,接受起来更易理解点:他人的文章写的再好,毕竟是别人的,学 ...

  9. 动态规划--找零钱有多少种方法

    问题: 给定数组arr,arr中的所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求换钱有多少种方法. 分析:arr长度为N,生成 ...

最新文章

  1. 19岁大学生网恋被骗318万!见到“女神”后傻了,对方竟有200斤!
  2. R使用深度学习LSTM构建时间序列预测模型
  3. 成功解决xgboost.core.XGBoostError: b'[20:58:45] C:\\Users\\Administrator\\Desktop\\xgboost\\dmlc-core\\s
  4. MongoDB基本概念和安装配置
  5. 吞噬星空怎么会有鸿蒙,论吞噬星空与鸿蒙的关系
  6. linux centos7 cuda安装
  7. Linux 系统编程技巧与概念 第12章 基于 TLV 传输
  8. CUDA Study Notes
  9. 雷锋科普:小米M2之芯高通APQ8064芯片组解析
  10. google,翻译英文网站
  11. 《计算机科学与工程导论:基于IoT和机器人的可视化编程实践方法第2版》一2.1 工作流和可视化编程...
  12. 【SpringCloud 2021.0.0】12、路由网关Gateway之简介 (spring-boot 2.6.3)
  13. 设计模式之浅浅的理解桥接模式
  14. MySQL Replication 梳理详解
  15. 打印ASCII码 c++
  16. python判定固定时长固定频率的音频是否连续
  17. sio.savemat得到空struct解决方法
  18. 养生需知:藏在水里的“杀机” 你遇到了吗
  19. 一篇搞定css基础(超详细,附代码)
  20. 【日本雅虎新闻推荐】:Embedding-based News Recommendation for Millions of Users(附开源代码)

热门文章

  1. Linux系统:软链接与硬链接的原理分析
  2. 第一季7:海思制作的rootfs包含哪些内容?
  3. appium+java(五)微信小程序自动化测试实践
  4. .NET 二维码生成(ThoughtWorks.QRCode)
  5. 用户登录和注册的功能
  6. C语言中的字节对齐以及其相关处理
  7. [翻译]API Guides - Bound Services
  8. VBA之六--EXCEL VBA两则
  9. asp.net mvc 实现文件管理参考资料
  10. 网络动态负载均衡算法分析