动态规划学习笔记(不定期更新)

最近刚开始接触动态规划(Dynamic Programming)算法,之前略有耳闻,一直觉得DP非常之高大上,看了某些题的DP解法也是云里雾里,哇擦?!这么几行代码就解决了?怎么全是数组操作?时间复杂度也很低的样子。其实不然,当我真正开始学习动态规划的时候才发现这货没那么玄乎。

把我对DP浅显的理解总结为以下几点:

1.空间换时间。

2.找到状态。

3.找到状态转移方程。

动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。为了能够快速的不重复的计算出最终解,所以需要保存每次状态的值,空间换时间就是这么个意思。

我举个最简单的例子,也是我看到动态规划后自己想到的,这个问题我们每个人学编程肯定都碰到过,斐波那契数列问题。好,我就按照我之前讲的理解来分析这题,先找到问题的状态,很明显不就是每次计算出来的这个值么。然后是状态转移方程,这更明显了,不就是斐波那契数列的定义么:f(n)=f(n-1)+f(n-2)。所以我觉得拿这题来入门动态规划再好不过了。之前的解法是递归,递归虽然简单易理解但是有大量的重复计算,效率极低,并且有函数栈溢出的危险,现在我们定义了状态和状态转移方程,代码就很好写了,保存每次的计算结果,最后一个结果就是整个问题的解。然后这个解法可以优化的,我们发现其实不用每次都保存中间结果,因为我们计算下一个状态时只需要上两次的结果,所以每次只要保存上两次的结果就可以了,这样空间复杂度也降到了常数级别,时间效率也大大增加。

代码如下:

int fib(int n)
{
	if(n==0||n==1) return n;

	int fia=0;
	int fib=1;
	int result=0;

	for(int i=2;i<=n;i++)
	{
		result=fia+fib;  //关键!状态转移方程!
		fia=fib;
		fib=result;
	}

	return result;
}

  

这个代码非常简单,谁都会写,我在学习动态规划之前就已经熟练可以写出上面的代码了,但是最最重要的是之前用动态规划思想分析的过程!动态规划是个庞大的话题,入门容易(我还没入门),想要真正理解DP的意义我还有很长的路要走,欢迎各位大神指点迷津。

本博客中LeetCode相关题目(陆续更新):

Unique Binary Search Trees
本博客内容与代码均为作者Jarvis原创,如若转载请注明。
时间: 2024-10-27 14:05:20

动态规划学习笔记(不定期更新)的相关文章

LDD和scull相关各种结构体的故事(学习笔记 不定期更新)

LDD和各种结构体的故事 struct scull_dev     位置:scull/scull.h struct scull_dev { struct scull_qset *data; /* Pointer to first quantum set */ int quantum; /* the current quantum size */ int qset; /* the current array size */ unsigned long size; /* amount of data

Linux学习笔记——Ubuntu更新软件源

0.前言 通过修改ubuntu软件源可提高apt命令下载安装软件的速度. 参考资料 [官方资料]--配置文件修改方法 [Ubuntu怎样修改软件源地址]--使用ubuntu软件中心修改(推荐) [at-get update错误处理] 1.使用ubuntu软件中心更新 请参考[Ubuntu怎样修改软件源地址]--来自百度经验 图1 打开软件和更新 图2 选择国内软件源 2.使用指令方法修改 [1]首先备份源列表 sudo cp /etc/apt/sources.list /etc/apt/sour

一步步写 CMOS 驱动模块 &lt;ELDD 学习笔记&gt; (最近更新,写到open release为止)

一步步写 CMOS 驱动模块 Let's implement a char driver to access the system CMOS. 首先仅仅是创建设备模块,最简单的,类似于前面hello world模块一样的东东,从最简单的框架慢慢搭 /************************************************************ code writer : EOF code date : 2014.08.15 code file : cmos_demo.c

python3.x学习笔记2018-02-02更新

前言:python3.x部分学习笔记,有意交流学习者可加wechat:YWNlODAyMzU5MTEzMTQ=.如果笔记内容有错,请指出来. *** 对数据类型的操作 可变数据类型:列表,集合,字典 列表: ``` li=['a','b'] 增: li.insert(2,'c') #在序号2位置上插入'c' li.append('d') #在列表末尾添加'd' li.extend(li2) #在列表li后面添加li2 删: li.remove('c') del li[2] li.pop(3) 改

java 数据库编程 学习笔记 不断更新

最近开始学习java,感觉java的数据库编程需要发个随笔记录一下,话不多说 切入正题. 一.数据库访问技术的简介 应用程序  →  执行SQL语句 →数据库 → 检索数据结果 → 应用程序   ( ODBC         JDBC(两个常用的API)) java主要使用的 JDBC驱动程序进行数据库的编程 Java 应用程序 <------> JDBC   <------>  数据库 二.JDBC 的体系结构 应用层 ↓ 驱动层 ↓ 各个接口 •Driver •Connecti

Pyqt4学习笔记-对话框(更新ing)

QInputDialog:可交互输入单个值的对话框.输入值可以是一个字符串,一个数字或者列表的一项. #!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui from PyQt4 import QtCore class InputExample(QtGui.QWidget): def __init__(self): super(InputExample, self).__init__() self.

Git学习笔记(持续更新)

强制同步为远程的代码 远程仓库回退了commit的情况下(第2条描述之情况),强制同步远程的代码到本地 #更新远程最新的所有代码,但是不merge或者rebase git fetch --all #直接reset到master,也就把刚才fetch的更新了 git reset --hard origin/master 回退版本 #回退本地版本git reset --hard <commit_id>#强制提交到服务器 git push origin HEAD --force 新建分支和远程分支

编程学习笔记 随时更新

自己把在学习中得到的经验随时写下来. ---------------------------------- VC中表示基地加偏移数据 int * p; p = (int *)0x001897D4; p=(int *)(*p+0x8); p=(int *)(*p+0x4); -------------------------------------

动态规划学习笔记--对于钢条切割方案的思考

1.问题描述 对一个长为n的钢条,给出不同长度钢条对应的单价,求出如何切割能使得该钢条的收益最大化. 2.问题解析 (1)暴力法 找出所有切割方案(共2^(n-1)种),计算出每种切割方案的收益,求最大值. 时间复杂度:O(2^(n-1)) (2)动态规划 这一问题是<算法导论>中,讲解动态规划的例题. 为什么这题能够用动态规划解决呢? 动态规划是用来解决具有以下性质的问题的: 1.最优子结构 2.重复子问题 这两个性质,显然前者更为重要,而后者没有也可以用动态规划解决(我现在这么认为). 动