博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SDUT 1008 最长公共子序列
阅读量:4359 次
发布时间:2019-06-07

本文共 2446 字,大约阅读时间需要 8 分钟。

最长公共子序列

  该题解参考这位博主https://blog.csdn.net/weyuli/article/details/9309121,我写这篇随笔只是为了解释一下这位博主写的代码,因为代码的注释很少,若是有跟我一样的新人怕是要耗费很长时间去理解题意,借此机会说说我对这个题的思路,并解释该博主的部分代码

内容:

  从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩下地字符按原来顺序组成的串。例如:“ ”,“a”,“xb”,“aaa”,“bbb”,“xabb”,“xaaabbb”都是串“xaaabbb”的子序列。(例子中的串不包含引号。)

编程求N个非空串的最长公共子序列的长度。限制:2<=N<=100;N个串中的字符只会是数字0,1,…,9或小写英文字母a,b,…,z;每个串非空且最多含100个字符;N个串的长度的乘积不会超过30000。

 

  此题的理解还需了解如何求两字符序列的最长公共字符子序列,若不懂请自行百度学习, 题目练习题号SDUT 2080。

  题目中有一句话:N个串的长度的乘积不会超过30000,这个地方告诉了我们数据的规模并且还强调了N个串长度的乘积,这里就要提一下,在求两字符序列的最长公共字符子序列这个问题中,我们为了方便理解,会画一个m * n的表格(m代表字符串x的长度,n代表字符串y的长度,x,y为任意两字符序列)来观察公共字符个数,两字符序列的最长公共字符子序列问题还可以看成二维公共子序列问题,因为解题的时候我们会建立一个二维数组。

  该题可以看成一个多维字符求最长公共子序列,但是题目说:N个子符串的乘积不会超过30000。这里我们就可以把这道多维问题转化为一个一维问题,参照求两字符序列的最长公共字符子序列问题把本该建立的多维表格给转化为一维数组。每一个index都对应着唯一的情况,即:多维字符串的长度为x1,x2,x3……xi时是否有公共字符。

  具体思路如下:

  建立一个二维字符数组保存字符,建立一个一维数组len来保存每一个字符数组的长度,一维数组L来保存多维字符数组长度的动态变化,用于求index(这部分请结合下面的代码利于理解),我们从每一个字符数组的末尾开始匹配,若都相等则把每一个多维数组长度L减一(所以我称它为动态长度数组),所以最长长度ret = DP(L) + 1;若只要有一个不同,则开始枚举每一种情况,详细请看代码:

#include 
#include
#include
using namespace std;char a[110][110];int dp[30000 + 10];int len[110];int n;int DP( int *x ){ int i, j, index, ret; for( i = 1; i <= n; i++ ) { if( x[i] == 0 ) { return 0; } } for( index = x[n] - 1, i = n - 1; i >= 1; i-- ) { index = index * len[i] + x[i] - 1; //转化为一维数组 } if( dp[index] >= 0 ) { return dp[index]; } //从每个字符串的末尾开始匹配 for( i = 2; i <= n; i++ ) { if( a[1][x[1] - 1] != a[i][x[i] - 1] ) { break; } } if( i > n ) { for( j = 1; j <= n; j++ ) { x[j]--; } ret = DP(x) + 1; for( j = 1; j <= n; j++ ) { x[j]++; } } else { ret = 0; int t; //开始枚举每一种情况 for( j = 1; j <= n; j++ ) { x[j]--; t = DP( x ); ret = max( ret, t ); x[j]++; } } dp[index] = ret; return ret;}int main(){ int T; int L[110]; scanf("%d", &T); while( T-- ) { scanf("%d", &n); for( int i = 1; i <= n; i++ ) { scanf("%s",a[i] ); len[i] = L[i] = strlen( a[i] ); } memset( dp, -1, sizeof(dp) ); printf("%d\n", DP( L ) ); } return 0;}

 

  

 

转载于:https://www.cnblogs.com/Naive-and-pure/p/10960355.html

你可能感兴趣的文章
FastJson
查看>>
excel4j
查看>>
Thread
查看>>
char * 与char []探究理解
查看>>
QT窗体显示在屏幕中间位置
查看>>
emmet使用技巧
查看>>
RPC-Thrift(二)
查看>>
MSSQL for Linux 安装指南
查看>>
【Golang 接口自动化08】使用标准库httptest完成HTTP请求的Mock测试
查看>>
前端必读:浏览器内部工作原理
查看>>
Uri、URL和URN三者的区别
查看>>
数据字典的转换
查看>>
二维数组按照指定的字段排序的函数
查看>>
linux安装Mac的默认Monaco字体
查看>>
java语言的特点
查看>>
关于动态添加iview admin路由以及刷新侧边栏
查看>>
ApplicationInsights的探测器尝鲜
查看>>
java 解析Json格式数据
查看>>
unix中的线程池技术详解
查看>>
CSS简介
查看>>