标签:style blog color 使用 os strong io for
1.动态规划和子序列
1.1 动态规划的特征:
a)最优子结构,求问题的解必须获取子问题的最优解;
b) 重叠子问题,使用原始的递归存在大量的重复计算。
1.2 子序列的概念:
a)子序列中的元素都是原字符串中的元素;
b)子序列中元素的排列顺序,与他们在原字符串中的顺序相一致;
c)子序列不同于子串,子序列中额元素在原字符串中未必是连续的。
e)eg.src = "foobar" ,那么 "fbr" 就是一个子序列。
2.求最长公共子序列的三个版本
2.1 最原始的递归求解,没有考虑重复计算问题。
#include <iostream> #include <string> using namespace std; int LCS(const string &str1, const string &str2, int i, int j); int main(int argc, const char *argv[]) { string str1 = "ABCBDAB"; string str2 = "BDCABA"; cout << LCS(str1, str2, str1.size(), str2.size()) << endl; return 0; } // i j 表示长度,即str1的前i个字节 和 str2的前j个字节 int LCS(const string &str1, const string &str2, int i, int j){ if(i == 0 || j == 0) return 0; if(str1[i-1] == str2[j-1]){ return LCS(str1, str2, i-1, j-1)+1; } else{ int ret1 = LCS(str1, str2, i-1, j); int ret2 = LCS(str1, str2, i, j - 1); return ret1 > ret2 ? ret1 : ret2 ; } }
2.2 画出上述递归树可以看到,大量的分支是重复的,那么重复的计算是否可以避免?显然可以,这里将所有的计算都存储在数组中,那么计算过的值就不会计算第二次,效率会大大提高。
#include <iostream> #include <string> #include <string.h> using namespace std; int memo[100][100];//全局数组 存储已经计算过的LCS[i][j] int LCS(const string &str1, const string &str2, int i, int j); int main(int argc, const char *argv[]) { string str1 = "ABCBDAB"; string str2 = "BDCABA"; memset(memo, -1, sizeof memo); cout << LCS(str1, str2, str1.size(), str2.size()) << endl; return 0; } // i j 表示长度,即str1的前i个字节 和 str2的前j个字节 int LCS(const string &str1, const string &str2, int i, int j){ if(memo[i][j] != -1) return memo[i][j]; if(i == 0 || j == 0) return 0; if(str1[i-1] == str2[j-1]){ memo[i][j] = LCS(str1, str2, i-1, j-1) + 1; return memo[i][j]; } else{ int ret1 = LCS(str1, str2, i-1, j); int ret2 = LCS(str1, str2, i, j - 1); memo[i][j] = ret1 > ret2 ? ret1 : ret2; return memo[i][j]; } }
2.3 非递归方法。从串长度为 0 开始依次求解,这里可作图研究,执行的过程就是填充一个二维数组的过程。
#include <iostream> #include <string> #include <stdlib.h> #include <string.h> using namespace std; /* * 最长公共子串 */ int main(int argc, const char *argv[]) { if(argc != 3){ cout << "Too Few Arguments" << endl; exit(EXIT_FAILURE); } string str1 = argv[1]; string str2 = argv[2]; int memo[100][100]; memset(memo, -1, sizeof memo); int i, j; for(i = 0; i <= str1.size(); i++) for(j = 0; j <= str2.size(); j++){ if(i == 0 | j == 0) memo[i][j] = 0; else{ if(str1[i-1] == str2[j-1]) memo[i][j] = memo[i-1][j-1] + 1; else memo[i][j] = memo[i-1][j] > memo[i][i-1] ? memo[i-1][j] : memo[i][j-1]; } } cout << memo[str1.size()][str2.size()] << endl; return 0; }
0804------算法笔记----------最长公共子序列,布布扣,bubuko.com
0804------算法笔记----------最长公共子序列
标签:style blog color 使用 os strong io for
原文地址:http://www.cnblogs.com/monicalee/p/3891349.html