动态规划--换零钱

题目描述

想兑换100元钱,有1,2,5,10四种钱,问总共有多少兑换方法

递归解法

#include<iostream>
using namespace std; const int N = 100;  
int dimes[] = {1, 2, 5, 10};  
int arr[N+1] = {1};  int coinExchangeRecursion(int n, int m) //递归方式实现,更好理解
{  if (n == 0)   //跳出递归的条件return 1;  if (n < 0 || m == 0)  return 0; return (coinExchangeRecursion(n, m-1) + coinExchangeRecursion(n-dimes[m-1], m));  //分为两种情况:换取当前面值的情况 + 没有换取当前面值的情况
}int main()
{int num=coinExchangeRecursion(N, 4); cout<<num<<endl; return 0; }

非递归解法

#include<iostream>
using namespace std; const int N = 100;  
int dimes[] = {1, 2, 5, 10};  
int arr[N+1] = {1};  int coinExchange(int n)   //非递归实现
{  int i, j;  //i从0 ~ 3     因为每个arr[j]都要有一次是假设兑换了dimes[i],所以我们要遍历一次for (i = 0; i < sizeof(dimes)/sizeof(int); i++){  for (j = dimes[i]; j <= n; j++)   //求,arr[j]的时候,可以看出arr[j] = arr[j] + arr[j-dimes[i]],//对应着上面的递归方式:arr[j]就是coinExchangeRecursion(n, m-1),//arr[j-dimes[i]]就是coinExchangeRecursion(n-dimes[m-1], m)arr[j] += arr[j-dimes[i]];  }  return arr[n];  
}  int main()
{int num2=coinExchange(N); cout<<num2<<endl; return 0;
}

下面写法更容易理解一些:

int coinExchange(int n)   //非递归实现
{  int i, j;  for(i=1; i<=n; i++){for (j=0; j<sizeof(dimes)/sizeof(int); i++){if (i>=dimes[j])arr[i] += arr[i-dimes[j]]}}return arr[n];  
}

方法总结

动态规划的经典之处把大问题分解成几个小问题解决
递归算法:100元的换法:零钱中有此面值与零钱中没此面值的两种情况,注意递归结束的条件
非递归算法:换100的零钱,那么先从换1、2、……的零钱算起,这个算法,最好转换成台阶走法的问题来理解
仔细推理可以看出arr[j] = arr[j-dimes[0]] + arr[j-dimes[1]] + arr[j-dimes[2]] + arr[j-dimes[3]] (j-dimes[i]>=0)

#include<iostream>
#include<vector>     //std::vector
#include <algorithm> //std::count
using namespace std; const int N = 100;  
int dimes[] = {1, 2, 5, 10};  
int arr[N+1] = {1}; 
vector<int> vv; int coinExchangeRecursion(int n, int m) //递归方式实现,更好理解
{  if (n == 0) {int i;for (i = 0; i < sizeof(dimes)/sizeof(int); i++) {int cnt = count(vv.begin(), vv.end(), dimes[i]);cout << dimes[i] << ": " << cnt << "\t";}cout  << endl;return 1;  }   //跳出递归的条件if (n < 0 || m == 0)  return 0;vv.push_back(dimes[m-1]);int yes = coinExchangeRecursion(n-dimes[m-1], m);vv.pop_back();int no = coinExchangeRecursion(n, m-1);return (no+yes);  //分为两种情况,如果没有换当前硬币,那么是多少?加上,如果换了当前硬币,总值减少,此时又是多少种兑换方法?
}int coinExchange(int n)   //非递归实现
{  int i, j;  for (i = 0; i < sizeof(dimes)/sizeof(int); i++)   //i从0 ~ 3     因为每个arr[j]都要有一次是假设兑换了dimes[i],所以我们要遍历一次{  for (j = dimes[i]; j <= n; j++)   //求,arr[j]的时候,可以看出arr[j] = arr[j] + arr[j-dimes[i]],//对应着上面的递归方式:arr[j]就是 coinExchangeRecursion(n, m-1),//arr[j-dimes[i]]就是coinExchangeRecursion(n-dimes[m-1], m)arr[j] += arr[j-dimes[i]];  }  return arr[n];  
}  int main(int argc, char *argv[])
{int num=coinExchangeRecursion(N, 4); cout<<num<<endl; int num2=coinExchange(N); cout<<num2<<endl; return 0; 
}

参考:

  • http://www.tuicool.com/articles/VBreAnY
  • http://taop.marchtea.com/02.05.html
  • 动态规划:从新手到专家

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508677.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学生表 课程表 成绩表 教师表常用SQL语句

学生表 课程表 成绩表 教师表 50个常用sql语句 建表 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 ---- If database exists the same name datatable deletes it. IF EXISTS(SELECT TABLE_NAME FRO…

Linux网络编程常见面试题

概述 TCP和UDP是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议。 TCP&#xff1a;传输控制协议&#xff0c;一种面向连接的协议&#xff0c;给用户进程提供可靠的全双工的字节流&#xff0c;TCP套接口是字节流套接口(stream socket)的一种。UDP&#xff1a;用户…

sizeof与offsetof有关的结构体详解

sizeof与offsetof在程序中经常遇到&#xff0c;但在面试中其应用使得许多小伙伴吃闭门羹&#xff0c;被面试官问得哑口无言。接下来对两者的应用做详细介绍。 关于sizeof 定义 sizeof乃C/C中的一个操作符(operator), 简单的说其作用就是返回一个对象或者类型所占的内存字节数…

linux线程间同步(1)读写锁

读写锁比mutex有更高的适用性&#xff0c;可以多个线程同时占用读模式的读写锁&#xff0c;但是只能一个线程占用写模式的读写锁。 1. 当读写锁是写加锁状态时&#xff0c;在这个锁被解锁之前&#xff0c;所有试图对这个锁加锁的线程都会被阻塞&#xff1b; 2. 当读写锁在读加…

linux线程间同步(1)互斥锁与条件变量

线程的最大特点是资源的共享性&#xff0c;但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步&#xff0c;最常用的是互斥锁、条件变量和信号量以及读写锁。 互斥锁(mutex) 互斥锁&#xff0c;是一种信号量&#xff0c;常用来防止两个进程或线…

Linux下压缩包生成与解压命令以及进度

不同后缀压缩包的打包与加压命令 .tar 解包&#xff1a;tar xvf FileName.tar打包&#xff1a;tar cvf FileName.tar DirName .gz 解压1&#xff1a;gunzip FileName.gz解压2&#xff1a;gzip -d FileName.gz压缩&#xff1a;gzip FileName .tar.gz 和 .tgz 解压&#xff1a;…

经典面试题

谷歌面试题&#xff1a;1024! 末尾有多少个0&#xff1f; 末尾0的个数取决于乘法中因子2和5的个数。显然乘法中因子2的个数大于5的个数&#xff0c;所以我们只需统计因子5的个数。 是5的倍数的数有&#xff1a; 1024 / 5 204个;对于25,50这些数据统计一次,但实际的是包含两个…

共享内存:mmap函数实现

内存映射的应用: 以页面为单位,将一个普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,这样用内存读写取代I/O读写,以获得较高的性能;将特殊文件进行匿名内存映射&#xff0c;可以为关联进程提供共享内存空间;为无关联的进程提供共享内存空间&#xff0c;一般也是将…

MSYS2开发环境搭建

MSYS2开发环境搭建 软件安装 下载msys2-x86_64软件包 https://www.msys2.org/&#xff0c;双击安装到某根目录下&#xff0c;比如D:\msys64。 pacman是MSYS2自带的软件管理工具&#xff1a; 可通过修改msys64\etc\pacman.d下的三个文件修改软件源&#xff0c;可供选择的源有…

设置python路径

在python开发应用&#xff0c;我们多数是通过pip、easy_install等工具将需要的python安装到自己机子上就可以应用了&#xff0c;但是我们完成开发给用户使用时&#xff0c;程序运行环境就是一个问题。当然&#xff0c;你可以要求客户按照你的方法安装依赖的库&#xff0c;这种方…

linux动态库查找路径以及依赖关系梳理

编译时与运行时库的路径 linux下&#xff0c;编译时与运行时库的搜索路径是不同的 运行时动态库的路径搜索顺序 LD_PRELOAD环境变量&#xff0c;一般用于hack 编译目标代码时指定的动态库搜索路径(指的是用 -wl,rpath 或-R选项而不是-L)&#xff0c;readelf -d命令可以查看编…

eclipse--android开发环境搭建教程

引言 在windows安装Android的开发环境不简单也说不上算复杂&#xff0c;但由于国内无法正常访问google给android开发环境搭建带来不小的麻烦。现将本人搭建过程记录如下&#xff0c;希望会对投身android开发的小伙伴有所帮助。 android开发环境部署过程 安装JDK环境 下载安装…

pip工具使用总结以及常用库PIL、freetype的安装

pip工具安装使用 pip为python库软件管理工具pip docs 安装 wget https://bootstrap.pypa.io/ez_setup.py -O - | python 安装setuptools https://pypi.python.org/pypi/setuptoolswget https://bootstrap.pypa.io/get-pip.py -O - | python 安装pip工具 ttps://pypi.python.…

【技巧】Chrome应用技巧

把Chrome浏览器变成文本编辑器 在浏览器地址栏中输入一行代码&#xff1a;data:text/html, <html contenteditable>&#xff0c;回车即可把浏览器变临时编辑器。【CtrlShiftJ】调出JavaScript控制台&#xff0c;在控制台输入&#xff1a; document.body.contentEditable…

eclipse--python开发环境搭建

pydev插件介绍 PyDev is a Python IDE for Eclipse pydev官方网站&#xff1a;http://www.pydev.org/ 在Eclipse中安装pydev插件 启动Eclipse, 点击Help->Install New Software… 在弹出的对话框中&#xff0c;点Add 按钮。 Name中填:Pydev, Location中填http://pydev.or…

Win7虚拟无线AP以及Android手机抓包

设备要求 Windows7操作系统装有无线网卡的笔记本或台式机无线网卡必须支持“承载网络” 查看无线网卡是否支持“承载” 方法一: 开始菜单→所有程序→附件→命令提示符→右键“以管理员权限运行”; 键入命令“netsh wlan show drivers”,查看“支持承载网络”这一项,如果是…

CMD命令之BAT脚本路径信息

CD命令解疑 cd是chdir的缩写&#xff0c;命令详解参见cd /? 可以看到/d参数的解释如下&#xff1a; 使用 /D命令行开关&#xff0c;除了改变驱动器的当前目录之外&#xff0c;还可改变当前驱动器。 通常我们在xp系统中打开cmd窗口时&#xff0c;会显示 C:\Documents and Se…

Ubuntu开发环境搭建

在虚拟中试玩Ubuntu1604版本&#xff0c;有关安装后一些配置记录如下&#xff0c;以备后用。 简单设置 root密码设置 虚拟机安装完成后&#xff0c;默认不弃用root用户&#xff0c;需要给root设置密码后使用 sudo passwd root终端加入右键中 将终端加入右键后&#xff0c;在某…

Python GUI Programming (Tkinter)

Tkinter编程实例 #!/usr/bin/python #coding:utf-8from Tkinter import * import sysreload(sys) sys.setdefaultencoding(utf-8)class GUI_WINDOWS:def __init__(self, root):self.root Frame(root)self.driver Noneself.friendEdit Noneself.bStopQuery Falseself.loadF…

【ubuntu 22.04】安装vscode并配置正常访问应用商店

注意&#xff1a;要去vscode官网下载deb安装包&#xff0c;在软件商店下载的版本不支持输入中文 在ubuntu下用火狐浏览器无法访问vscode官网&#xff0c;此时可以手动进行DNS解析&#xff0c;打开DNS在线查询工具&#xff0c;解析以下主机地址&#xff08;复制最后一个IP地址&a…