多年前就听过这个动态规划,最近在复习常用算法的时候才认真学习了一下,发现蛮有意思,和大家安利一波。

定义:

准确来说,动态规划师吧一个复杂问题分解成若干个子问题,并且寻找最优子问题的一种思想,而不是一种特定的算法。

听上去和我们常用的递归有点类似,但是注意:其中子问题的解被重复使用。也就是利用这个特性,我们可以把一个复杂的问题抽象转换成一个简单二维表来进行推演。

动态规划的解题关键在于:

  • 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版本)的更多相关文章

  1. 上传golang 版本SDK

    在上传的时候,文件都上传成功了,但是返回的信息里面errcode 404 token 是"".是不是因为我的callbackUrl(随便写的) 写错导致的. 上传golang 版本 ...

  2. Golang版本的rocksdb-对gorocksdb的封装

    rocksdb的优秀特性不用多说,但是它是用c++语言写的,就是这一个特点就把很多人拦住了.虽然rocksdb官方也有Java版本,但是Golang的发展速度让人不容小觑,而且由于golang原生对高 ...

  3. Golang 版本发布 与 TIOBE 排名

    2016年国庆节(10月1日)开始接触 Go 语言,记录一下它的 版本发布 与 TIOBE 排名: Golang 排行榜 月份 版本 排名 备注 2012.03 1.0             201 ...

  4. EasyDarwin开源流媒体服务器Golang版本:服务端录像功能发布

    EasyDarwin开源流媒体服务器(www.easydarwin.org)现在使用Go版本实现了.最新的代码提交,已经支持了推流(或者拉流)的同时进行本地存储. 本地存储的原理,是在推流的同时启动f ...

  5. 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 ...

  6. [原创] linux 下上传 datapoint数据到yeelink 【golang版本】同时上传2个数据点

    /* Create by sndnvaps<sndnvaps@gmail.com> * data: 2015-04-12* upload 2 datapoint to yeelink.ne ...

  7. golang 版本 gearman 试用

    g2 是golang 版的gearman 实现,包含了server (支持leveldb,以及metrics).client 代码.worker 代码 使用上还是很方便的,同时部署也比较简单,结合do ...

  8. TLS示例开发-golang版本

    目录 前言 制作自签名证书 CA 服务器证书相关 客户端证书相关 证书如何验证 在浏览器中导入证书 导入证书 修改域名 golang服务端 目录 main.go 测试 参考 前言 在进行项目总结的时候 ...

  9. [原创] linux 下上传 datapoint数据到yeelink 【golang版本】

    package main /* Create by sndnvaps<sndnvaps@gmail.com> * date : 2015-04-05 * upload datapoint ...

随机推荐

  1. SpringCloud 中集成Sentinel+Feign实现服务熔断降级

    Sentine 1.背景 Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度来帮助用户保护服务的稳 ...

  2. 【XSY2495】余数

    Input Output Input 3 4 Output 4 HINT 原式 =n*m-n除以i向下取整 用数论分块做就可以了 #include<bits/stdc++.h> #defi ...

  3. Lab_1:练习3——分析bootloader进入保护模式的过程

    文章链接:https://www.cnblogs.com/cyx-b/p/11809742.html 作者:chuyaoxin 一.实验内容 BIOS将通过读取硬盘主引导扇区到内存,并转跳到对应内存中 ...

  4. Vue项目中执行npm run dev 不报错也不显示点击的地址链接

    问题描述: 输入npm run dev 没有报错也没有显示可以点击的地址链接,如下图: 解决方法: 具体配置: autoOpenBrowser默认为false,改为true.重新 npm run de ...

  5. 大数据之路day01_1--Java下载、安装等配置

    从今天开始,我就正式的走上大数据的道路了,如果说我为啥要去学习大数据,可能我的初衷是以后可以接触到人工智能方面的技术,后来在自学的过程中发现,学习人工智能,需要扎实的算法,以及对大量数据的处理,再者, ...

  6. 你了解MySQL中的日志吗?

    MySQL中有两类非常重要的日志,一类是redo log(重做日志),一类是bin log(归档日志) redo log 重做日志利用的,是MySQL中,常见的WAL技术,WAL技术的全程是:Writ ...

  7. Win7无法远程桌面

    Win7在设置里开启允许其他计算机远程连接,但局域网计算机还是连不上: 然后点击上面的为远程桌面启用windows防火墙例外,发现远程桌面是允许的: 实际上这个不是,问题的真正原因在于用于远程的338 ...

  8. docker swarm 过滤器affinity 限制副本不会出现在同一个节点上

    affinity:container!=容器服务名称(可以是正则) 举个例子:stack_ds.yaml # cat stack_dsc.yaml version: '3.0' services: t ...

  9. nuxt遇到的问题(一)window 或 document is not defined

    因为用了VUE做的官网,既然是官网了避免不了SEO的问题了(该死当初就不应该选择用vue) 很自然就是选择了使用nuxt.js来做ssr预渲染了. 因为网站不是响应式的,PC / 移动端要进行对应跳转 ...

  10. PowerMock学习(三)之Mock局部变量

    编写powermock用例步骤: 类上面先写这两个注解@RunWith(PowerMockRunner.class).@PrepareForTest(StudentService.class) 先模拟 ...