d一、字符串删字符后最长不降子序列
1.问题描述
请在字符串“UXDQIRQFJEUURYHKNTUVPBYIDYXQCXITPVSNSKWJIIJTZ“中删除若干个字符后,余下的字符构成不降子序列(即序列从第2个字符开始,每一个字符的ASCII码不小于它前面字符的ASCII码)。求最长的不降子序列。
2.设计要点
给定一个由n个字符组成的字符串,从字符串中删除若干个字符后,使剩下的字符串构成非子序列。设字符串的各个字符a(1),a(2),...,a(n),对每一个字符操作(删除还是不删)为一个阶段,共为n个阶段。
⑴建立递推关系
设置b数组,b(i)表示序列的第i个字符到最后第n个字符的最长非降子序列的长度,i=1,2,...,n。对所有j>i,比较当a(i)<=a(j)时的所有b(j)的最大值,显然b(i)为这一最大值加1,表示加上a(i)本身这一项。
因而有递推关系:
b(i)=max(b(j))+1 (a(i)<=a(j), 1<=i<j<=n) 边界条件:b(n)=1
⑵逆推计算最优值
逆推依次求得b(n-1),...,b(1),比较这n-1个值得其中的最大值lmax,即为所求的最长非降子序列的长度,即最优值
⑶构造最优解
从序列的第1项开始,依次输出b(i)分别等于lmax,lmax-1,...,1且a(i)不小于其前面输出项a(j),这就是所求的一个最长非降子序列。
3.代码实现
二、最长公共子序列
1.问题提出
一个序列的子序列是在该序列中删去若干项后所得到的序列。例如,"bcba"是"abcbdab"和"bdcaba"的公共子序列。给定两个序列X={x1,x2,...,xm}和Y={y1,y2,...,yn},找出序列X和Y的最长公共子序列。
2.设计要点
最长公共子序列问题具有最优子结构性质,应用动态规划设计求解。
⑴建立递推关系
设序列X={x1,x2,...,xm}和Y={y1,y2,...,yn}的最长公共子序列为Z={z1,z2,...,zk},{x1,x2,...,xm}与{y1,y2,...,yn} (i=1, ..., m; j=1, ..., n)的最长公共子序列的长度为c(i,j)。
若i=m+1或j=n+1,此时为空序列,c(i, j)=0(边界条件)。
若x(1)=y(1),则有z(1)=x(1),c(1,1)=c(2,2)+1(其中1为z(1)这一项)。
若x(1)!=y(1),则c(1,1)取c(2,1)与c(1,2)中的较大者。
一般地,有递推关系:
若x(i)=y(i),则c(i,j)=c(i+1,j+1)+1 (1<=i<=m, 1<=j<=n);
若x(i)!=y(i),则c(i,j)=max(c(i+1,j),c(i,j+1))。
边界条件:c(i,j)=0 (i=m+1或j=n+1)
⑵逆推计算最优值
根据以上递推关系,逆推计算最优值c(1,1)流程为:
⑶构造最优值
为构造最优值,即最优救出最长最长公共子序列,设置数组s(i,j),当x(i)=y(j)时s(i,j)=1;当x(i)!=y(j)时s(i,j)=0。
X序列的每一项与Y序列的每一项逐一比较,根据s(i,j)与c(i,j)取值具体构造最长公共子序列。
实施x(i)与y(j)比较,其中i=1,2,...,m;j=1,2,...,n;变量t从0开始取值,当确定最长公共子序列一项时,t=j+1。这样处理可避免重复取项。
若s(i, j)=1且c(i,j)=c(1,1)时,取x(i)为最长公共子序列的第1项;
随后,若s(i,j)=1且c(i,j)=c(1,1)-1时,取x(i)最长公共子序列的第2项;
一般地,若s(i,j)=1且c(i,j)=c(1,1)-2时(w从0开始,每确定最长公共子序列的一项,w增1),取x(i)最长公共子序列的第w+1项。
构造最长公共子序列描述:
⑶代码实现