码迷,mamicode.com
首页 > 其他好文 > 详细

动态规划 入门版

时间:2016-04-22 16:20:50      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:

解决动态规划问题的方法很多,现在先看看最容易想到的------递归法。

核心代码就那么一段:

1 int solve(int i, int j)
2 {
3 return dp[i][j] + (i == 3 ? 0 : max(solve(i + 1, j), solve(i + 1, j + 1)));
4 }

 

solve(i,j)就是节点(i,j)的最大值。

递推法:
思想就是从头开始一层一层推,由于每个节点上一级(最上面一个节点除外)都有两个上级节点,所以dp[i][j]就可以使它等于本身加上上一级中较大的一个数,从而不断推到底层,那么最大的肯定就在最底层了。

1 for (int i = 0; i < n; i++)
2 for (int j = 0; j < i+1; j++)
3 {
4 if (j == 0)dp[i][j] = dp[i][j];
5 else dp[i][j] += max(dp[i - 1][j], dp[i - 1][j - 1]);
6 }

 

之后想到这种方法并非递推中最好的,因为还要在底层中用循环找最大值,其实最好的方法是从底层往上递推,最后结果就是dp[0][0]。


记忆化搜索:
基本是结合了前两者的特点:用递归的总体思想,但其中掺加了递推法的保存计算过的值。也就是第一次使用递归时将它得出的节点的值保存下来,以后再使用到这个节点时就可以直接使用这个值了,而不用再去递归。但里面有一点小技巧:你怎么知道它之前有没有递归算出过答案呢?就是设两个数组,第一个数组dp用来存放已经计算过的节点,第二个数组是真正完整的数组。一开始dp数组用什么东西标识(比如对于一棵树中全是整数的话就用-1来初始化dp)。

int solve(int i, int j)
{
if (dp[i][j] > 0)return dp[i][j];
return dp[i][j] = a[i][j] + (i == 3 ? 0 : max(solve(i + 1, j), solve(i + 1, j + 1)));
}

 

动态规划 入门版

标签:

原文地址:http://www.cnblogs.com/nkuhjp/p/5421472.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!