DP动态规划与记忆化搜索的联系与区别

之前遇到好几个不会做的DP题,请教小伙伴,小伙伴都是用记忆化搜索打发我

今天闲下来认真看了看,感觉似乎理解了一些

试着写了下LCS(最长公共子序列),代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 10010
#define ll long long
using namespace std;

int dp[MAXN][MAXN];
string str1, str2;

/*//记忆化搜索
int LookUp(int i, int j) {
    if(dp[i][j])
        return dp[i][j];
    if(i==0 || j==0)
        return 0;
    if(str1[i-1] == str2[j-1]) {
        dp[i][j] = LookUp(i-1, j-1)+1;
    }
    else dp[i][j] = max(LookUp(i-1, j), LookUp(i, j-1));
    return dp[i][j];

}
*/

int main(void) {
    
    cin >> str1 >> str2;

  //  LookUp(str1.size(), str2.size());
    for(int i=1; i<=str1.size(); ++i) {
        for(int j=1; j<=str2.size(); ++j) {
            if(str1[i] == str2[j])
                dp[i][j] = dp[i-1][j-1]+1;
            else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
        }
    }
    cout << dp[str1.size()][str2.size()] << endl;
    return 0;
}

可以注意到,原理都是相同的,只是实现方法不同

可以明显的发现有以下几点不同:

1、DP是从下向上,而记忆化搜索是从上向下的

2、DP是从下向上,为了求到最终结果需要把过程中所有的值都保存下来,以便下一步可能会使用,而因为记忆化搜索是从上向下的,所以求解过程求的都是需要的;也就是说不需要的值并没有求

3、记忆化搜索使用递归实现的,从上面的代码可以看出

如果一个dp[i][j]的值已经求过,使用DP直接调用即可;而使用记忆化搜索则要进入递归

如果一个dp[i][j]的值还未求过,使用DP直接求得,而使用记忆化搜索则要进入递归中去求,而这个递归很有可能是多重的

这样一来DP在时间上几乎总是优于记忆化搜索的

问了好几个人都说记忆化搜索更容易想到,但我为什么觉得DP更容易想到呢《DP动态规划与记忆化搜索的联系与区别》

    原文作者:动态规划
    原文地址: https://blog.csdn.net/u011639256/article/details/29389951
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞