动态规划---01背包与记忆化搜索
来源:互联网 发布:看韩剧用什么软件 编辑:程序博客网 时间:2024/06/09 15:18
动态规划是一种高效的算法。在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之。因此我们使用动态规划的时候,原问题必须是重叠的子问题。运用动态规划设计的算法比一般朴素算法高效很多,因为动态规划不会重复计算已经计算过的子问题。因为动态规划又可以称为“记忆化搜索”。
01背包是介绍动态规划最经典的例子,同时也是最简单的一个。我们先看看01背包的是什么?
问题(01背包): 有n个重量和价值分别为Wi和Vi的物品。从这些物品中挑出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。这就是被称为01背包的问题。在没学习动态规划之前,我们看到这个问题第一反应会用dfs搜索一遍。那我们先使用这种方法来求解01背包问题:
//n,W 如题意所述int W, n;//w[i]和v[i]分别表示Wi,Viint w[MAXN], v[MAXN];//从第i个物品开始挑选总重量小于j的部分int dfs(int i, int j){ int res; //已经没有剩余物品 if(i == n) res = 0; //无法挑选第i个物品 else if(j < w[i]) res = dfs(i+1, j); //比较挑和不挑的情况,选取最大的情况 else res = max(dfs(i+1, j), dfs(i+1, j-w[i])+v[i]); return res;}
乍一看dfs好像就可以解决这个问题,那还有动态规划什么事。然而我们仔细分析一下时间复杂度,每一种状态都用选或者不选两种可能。所以我们可以得出使用dfs的时间复杂度为O(2^n)。显然这个方法不是一个很好的方法,因为这个时间复杂度太高了。我们仔细研究可以发现,造成时间复杂度这么高的原因是重复计算。既然我们找到复杂度这么高的原因,那我们就可以想办法减少它重复计算的次数。仔细分析容易想到,使用一个二维数组来记录每一次搜索的答案,这样我们就避免了重复计算。
//n,W 如题意所述int W, n;//w[i]和v[i]分别表示Wi,Viint w[MAXN], v[MAXN];//保存每一次搜索的答案//初始化dp数组的值,使其全为-1int dp[MAXN][MAXN];//从第i个物品开始挑选总重量小于j的部分int dfs(int i, int j){ if(dp[i][j] >= 0) return dp[i][j]; int res; //已经没有剩余物品 if(i == n) res = 0; //无法挑选第i个物品 else if(j < w[i]) res = dfs(i+1, j); //比较挑和不挑的情况,选取最大的情况 else res = max(dfs(i+1, j), dfs(i+1, j-w[i])+v[i]); return res;}
这样的小技巧,我们称之为记忆化搜索。我们只是小小的改变就让它的时间复杂度降低至O(nW)。
仔细分析,可以发现我们还可以有更简单的写法:
//dp[i+1][j] 表示从前i个物品挑选出总重量超过j的物品时,背包中的最大价值void solve(){ //还没开始挑选的时候,背包里的总价值为0 for(int j = 0; j <= W; j++) dp[0][j] = 0; for(int i = 0; i < n; i++){ for(int j = 0; j <= W; j++){ if(j < w[i]) dp[i+1][j] = dp[i][j]; else dp[i+1][j] = max(dp[i+1], dp[j-w[i]]+v[i]); } }}
使用递推方程直接求解的方法,我们称之为dp。因为他每一次的选取,都在动态的计算最优的情况。当然可能他局部不是最优,但是整体一定是最优解。这就是他和贪心算法最大的不同,贪心算法,每一次都是最优,但是整体不一定不是最优。附上一道习题:hdu2602Bone Collector
2 0
- 动态规划---01背包与记忆化搜索
- 动态规划---01背包与记忆化搜索
- 练习题 No.5 背包问题(动态规划-记忆化搜索)
- 动态规划-记忆化搜索
- 01背包 记忆化搜索
- 01背包 记忆化搜索
- 【记忆化搜索】01背包
- poj 1088 记忆化搜索||动态规划
- 动态规划和记忆化搜索
- 记忆化搜索算法之动态规划
- poj 1088+动态规划+记忆化搜索
- EOJ 1823 【动态规划】 【记忆化搜索】
- 动态规划_记忆化搜索
- 动态规划_记忆化搜索
- POJ088滑雪(记忆化搜索|动态规划)
- 动态规划(记忆化搜索)
- hdu1501 zipper【记忆化搜索】【动态规划】
- 动态规划 乘电梯 记忆化搜索
- App Components --2.0
- 【USACO题库】2.3.4 Money Systems货币系统
- Mason 入门例子3 --- 让学生动起来
- Android 大杂烩工程之ListView的开发详解
- javascript date类型用法
- 动态规划---01背包与记忆化搜索
- Guice学习之Bindings
- Howto: Backup and restore your system!
- UIScrollView的属性总结
- 第五周项目2-游戏中的角色类(1)
- Object-C基础(2)—— NSLog函数
- JS表格组件神器bootstrap table详解(基础版)
- UIScrollView上的控件处理touch事件
- MySQL数据库MyISAM和InnoDB存储引擎的比较