记忆化搜索---最长子串
来源:互联网 发布:尊而光律所怎么样知乎 编辑:程序博客网 时间:2024/06/05 11:13
问题:两个字符串求其最长可不连续相同子串,打印出子串
思考:这样的问题可以用回溯的方法,通过递归把每种情况都遍历一遍,再得出最佳结果,但是这样的解法的时间发杂度为2的n次方,当字符串长度达到10以上时首先空间会溢出,再者时间消耗太多。所以考虑用记忆化搜索,用二维数组存储两个字符串中没两个元素之间的关系。
在用二维数组存储关系的难题在于如何去遍历,让每个节点的值是到达它的最大值,从子串的定义可以看出,当遍历到的节点为真时,就需要从它的下一列和下一行开始前进,所以我们需要遍历完它的右下方的所有节点。在这种情况下的时间复杂度为n的4次方。
#include <cstdio>#include <cstring>#include <algorithm>#include <stack>using namespace std;int mtx[1001][1001];int fa[1001];//每个节点的双亲节点int main(){ char s1[1001], s2[1001]; int l1, l2; int T; scanf("%d", &T); while(T--){ memset(fa, -1, sizeof(fa)); scanf("%s%s", s1, s2); l1 = strlen(s1); l2 = strlen(s2); for(int i = 0; i < l1; i++) for(int j = 0; j < l2; j++) mtx[i][j] = (s1[i] == s2[j]);//记录两个字符串元素之间关系 for(int i = 0; i < l1; i++) for(int j = 0; j < l2; j++) //从每个起点出发,且每个起点都在遍历过的起点的右下方 if(mtx[i][j]) for(int r = i+1; r < l1; r++) for(int s = j+1; s < l2; s++) if(mtx[r][s] && mtx[r][s] < mtx[i][j]+1) { //当该点元素不为零时,给它附上最大值 mtx[r][s] = mtx[i][j] + 1; fa[r] = i; } int ma = 0, si = 0, sj = 0;//找到最大终点 for(int i = 0; i < l1; i++) for(int j = 0; j < l2; j++) if(mtx[i][j] > ma) { si = i; sj = j; } stack<int> st;//以下是正序输出 while(si != -1){ st.push(si); si = fa[si]; } while(!st.empty()){ printf("%c", s1[st.top()]); st.pop(); } printf("\n"); }}
阅读全文
0 0
- 记忆化搜索---最长子串
- 最长公共子序列,记忆化搜索
- 回文子串 记忆化搜索(DP)
- hdu 1503 + 简单dp ( 最长公共子序列型)+记忆化搜索+stl
- nyoj 17 单调递增最长子序列(dp---记忆化搜索||穷举|| nlogn算法)
- 最长上升子序列 记忆化讲解
- (POJ 1159)Palindrome <最长公共子序列 / 滚动数组优化 / 记忆化搜索> 简单回文数
- 【动态规划】【记忆化搜索】关键子工程
- 记忆化搜索例题
- PKU1088---记忆化搜索
- PKU1088 记忆化搜索
- HDU1078 记忆化搜索
- HDU1501 记忆化搜索
- HDU1978 记忆化搜索
- poj1661 记忆化搜索
- zoj1107记忆化搜索
- poj1191(记忆化搜索)
- 滑雪 记忆化搜索
- jquer选择器的总结
- IT的道德与伦理
- Java学习11:final关键字
- 关于变量、对象(类)、String类的理解与区分
- 【51nod 1009】数字1的数量 【数位DP 模板】
- 记忆化搜索---最长子串
- 再见 2017,你好 2018
- JAVA JNI开发应用实例
- 1504.ICCVPartial Person Re-Identification 论文笔记
- Redis分布式锁的正确实现方式(Java版)
- 12月第一篇博客
- java多线程[7]:CyclicBarrier
- 深度学习之Caffe完全掌握:用C++开发(自定义)网络层
- TIPS