有趣的动态规划(golang版本)
多年前就听过这个动态规划,最近在复习常用算法的时候才认真学习了一下,发现蛮有意思,和大家安利一波。
定义:
准确来说,动态规划师吧一个复杂问题分解成若干个子问题,并且寻找最优子问题的一种思想,而不是一种特定的算法。
听上去和我们常用的递归有点类似,但是注意:其中子问题的解被重复使用。也就是利用这个特性,我们可以把一个复杂的问题抽象转换成一个简单二维表来进行推演。
动态规划的解题关键在于:
- 1.根据问题可能性进行拆分。
从最简单的情况下进行分析,从下往上逐步分析。 - 2.找到状态转移方程式,保存最优解。
方程式其实就是在满足某个条件下的递推通项公式,同时也要注意条件范围和边界处理。
最有名的是背包问题:将N种类型的物件放到一个容量为M的背包里面,寻找最优解。
一般来说可以用暴力枚举的方式去算近似最优,但是从空间复杂度和时间复杂度来看使用动态规划更好,因为每一步的结果会保存下来给下一步计算使用,节约了不少时间消耗,最终算法性能极高。
下面举一个典型的例子,来自牛客网的一道"凑整题":
给你六种面额 1、5、10、20、50、100 元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0~10000的非负整数)的不同组合的个数。
仔细分析后发现,这是一个用不同类型的面额组合拼凑固定金额的组合最优解问题。由于N为0 ~ 10000的非负数,我们可以假设N取10来分析。
分析结果如图:
伪代码如下:
if (j - price[i] >= 0) {
Fn(amount) = Fn(j - price[i]) + Fn-1(amount);
} else {
Fn(amount) = Fn-1(amount);
}
其中的Fn函数可以用一个二维数组来实现,第二维为面额个数(即n),第一维度为amount+1种,用于对应的组合数。
用golang实现如下:
func getTheNum(num int) int {
var dp [5][10000]int
moneys = int[...] {1, 5, 10 ,20 , 50, 100}// 面额数组
for i := 0; i < 5; i++ { // 用前i种面额拼凑1rmb的方法数均为1
dp[i][0] = 1
}
for i := 0; i <= num; i++ { // 用1rmb面额拼凑0金额的方法数都为1
dp[0][i] = 1
}
for i := 1; i < 5; i++ { // 每一种面额组合递推
for j := 1; j <= num; j++ {
if j - moneys >= 0 { // 当当前金额大于这次循环的面额值,则组合数等于当前i种面额拼凑j金额的组合数+前i+1种面额拼凑j - moneys[i]金额的组合数
dp[i][j] = dp[i-1][j] + dp[i][j - moneys[i]]
} else {
dp[i][j] = dp[i-1][j]
}
}
}
return dp[4][num] // 返回最后一项
}
还可以进一步简化,因为二维数组保存的结果在每一次循环判断中都被保存下来了,所以用一维数组也可以保留。改进实现如下:
func SimpleGetNum(num int) int {
var dp [10000]int
moneys = int[...] {1, 5, 10 ,20 , 50, 100}// 面额数组
for i := 0; i <= num; i++ { // 用1rmb面额拼凑0金额的方法数都为1
dp[i] = 1
}
for j := 1; j <= 5; j++ {
for i := 1; i <= num; i++ {
if i >= moneys[j] { // 当前面金额大于面额的时候需要计算前i种面额组合出i - moneys[j]的方法数
dp[i] += dp[i - moneys[j]]
}
}
}
return dp[num]
}
探索的过程就如同RPG游戏,算法真的是一个很有趣的事情,很多都像精巧的数学问题的代码化。
有趣的动态规划(golang版本)的更多相关文章
- 上传golang 版本SDK
在上传的时候,文件都上传成功了,但是返回的信息里面errcode 404 token 是"".是不是因为我的callbackUrl(随便写的) 写错导致的. 上传golang 版本 ...
- Golang版本的rocksdb-对gorocksdb的封装
rocksdb的优秀特性不用多说,但是它是用c++语言写的,就是这一个特点就把很多人拦住了.虽然rocksdb官方也有Java版本,但是Golang的发展速度让人不容小觑,而且由于golang原生对高 ...
- Golang 版本发布 与 TIOBE 排名
2016年国庆节(10月1日)开始接触 Go 语言,记录一下它的 版本发布 与 TIOBE 排名: Golang 排行榜 月份 版本 排名 备注 2012.03 1.0 201 ...
- EasyDarwin开源流媒体服务器Golang版本:服务端录像功能发布
EasyDarwin开源流媒体服务器(www.easydarwin.org)现在使用Go版本实现了.最新的代码提交,已经支持了推流(或者拉流)的同时进行本地存储. 本地存储的原理,是在推流的同时启动f ...
- golang 版本升降之后报错——imports runtime: C source files not allowed when not using cgo or SWIG
问题: golang 升级或者降级版本之后,执行编译报错如下: package github.com/onsi/ginkgo/ginkgo imports runtime: C source file ...
- [原创] linux 下上传 datapoint数据到yeelink 【golang版本】同时上传2个数据点
/* Create by sndnvaps<sndnvaps@gmail.com> * data: 2015-04-12* upload 2 datapoint to yeelink.ne ...
- golang 版本 gearman 试用
g2 是golang 版的gearman 实现,包含了server (支持leveldb,以及metrics).client 代码.worker 代码 使用上还是很方便的,同时部署也比较简单,结合do ...
- TLS示例开发-golang版本
目录 前言 制作自签名证书 CA 服务器证书相关 客户端证书相关 证书如何验证 在浏览器中导入证书 导入证书 修改域名 golang服务端 目录 main.go 测试 参考 前言 在进行项目总结的时候 ...
- [原创] linux 下上传 datapoint数据到yeelink 【golang版本】
package main /* Create by sndnvaps<sndnvaps@gmail.com> * date : 2015-04-05 * upload datapoint ...
随机推荐
- 机器阅读理解(看各类QA模型与花式Attention)
目录 简介 经典模型概述 Model 1: Attentive Reader and Impatient Reader Model 2: Attentive Sum Reader Model 3: S ...
- 20190730_图像混合_opencv_python
今天学习了 图像的混合 教程上的代码很简单,但是绝对运行不出来 教程名称:OpenCV-Python 中文教程 #图像融合 import cv2 import numpy as np import m ...
- NOIP提高组/CSP-S复赛需掌握的算法
1.排序算法(快排.选择.冒泡.堆排序.二叉排序树.桶排序) 2.DFS/BFS 也就是搜索算法,剪枝务必要学! 学宽搜的时候学一下哈希表! 3.树 ①遍历 ②二叉树 ③二叉排序树(查找.生成.删除) ...
- [wcp部署]Linux(Ubuntu)安装部署WCP
1.安装JAVA运行环境 配置环境变量及安装jdk mkdir /usr/local/java tar -zxvf jdk-8u31-linux-x64.gz #解压jdk包 mv jdk1.8.0_ ...
- Hive数据仓库你了解了吗
在工作中我们经常使用的数据库,数据库一般存放的我们系统中常用的数据,一般为百万级别.如果数据量庞大,达到千万级.亿级又需要对他们进行关联运算,该怎么办呢? 前面我们已经介绍了HDFS和MapReduc ...
- NOIP 模拟赛 23 T4 大逃亡O(二分+广搜)(∩_∩)O
题目描述 给出数字N(1≤N≤10000),X(1≤x≤1000),Y(1≤Y≤1000),代表有N个敌人分布一个X行Y列的矩阵上,矩形的行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x ...
- python关于urllib库与requests
对于这两个库来说个人推荐使用requests库 下面用实例来说明 urllib库: requests库: 实现同样功能: 实现同样的功能下urllib比request步骤更复杂,这个对于我们编程来说是 ...
- js获取文件里面的所有文件名
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Linux之ant安装部署
接下来呢,就开始ant的部署,具体分为如下几个步骤: 1. 获取介质: 在apache的官网中直接下载,下载地址为:http://ant.apache.org/ 下载需要的版本即可: 2. 复制到us ...
- win10添加启动项目
Win10启动文件夹一般位于C:\ProgramData\Microsoft\Windows\Start Menu(开始菜单)\Programs(程序)\StartUp(启动)目录,我们主要讲希望添加 ...