对于求取两个长度为n的字符串的最长公共子序列问题,利用(57)策略可以有效地避免子串最长公共子序列的重复计算,得到时间复杂度为O(n2)的正确算法。A.贪心B.分治C.分支—限界D.动态规划

题目

对于求取两个长度为n的字符串的最长公共子序列问题,利用(57)策略可以有效地避免子串最长公共子序列的重复计算,得到时间复杂度为O(n2)的正确算法。

A.贪心

B.分治

C.分支—限界

D.动态规划


相似考题
参考答案和解析
正确答案:D
解析:对于求取两个长度为n的字符串的最长公共子序列(LCS)问题,是利用动态规划策略解决的经典问题之一。利用动态规划策略求解该问题时可以通过查表得到已经计算出的子串的最长公共子序列,从而避免重复计算。例如,利用动态规划算法可以得到串1,0,0,1,0,1,0,1>和0,1,0,1,1,0,1,1>的最长公共子序列的长度为6,如“101011”。
更多“对于求取两个长度为n的字符串的最长公共子序列问题,利用(57)策略可以有效地避免子串最长公共子序列的重复计算,得到时间复杂度为O(n2)的正确算法。A.贪心B.分治C.分支—限界D.动态规划”相关问题
  • 第1题:

    阅读以下程序说明和C程序,将应填入(n)处的子句,写在对应栏内。

    【程序说明】

    函数int commstr(char * str1,char * str2,int * sublen)从两已知字符串str1和str2中,找出它们的所有最长的公共子串。如果最长公共子串不止1个,函数将把它们全部找出并输出。约定空串不作为公共子串。

    函数将最长公共子串的长度送入由参数sublen所指的变量中,并返回字符串str1和str2的最长公共子串的个数。如果字符串str1和str2没有公共子串,约定最长公共子串的个数和最长公共子串的长度均为0。

    【程序】

    int strlen(char * s)

    {char *t=s;

    while( * ++);

    return t-s-1;

    }

    int commstr(char) *str1,char *str2,int *sublen

    { char*s1, *s2;

    int count=0,len1 ,len2,k,j,i,p;

    len1:=strlen(str1)

    len2 = strlen(str2);

    if(len1>len2)

    {s1=str1 ;s2=str2;}

    else {len2 = len1;s1 = str2;s2 = str1;}

    for(j=len2;j>0;j--) /*从可能最长子串开始寻找*/

    {for(k=0;(1)<:len2;k++) /*k为子串s2的开始位置*/

    {for(i=0;s1[(2)]!='\0';i++;) /*i为子串s1的开始位置*/

    { /*s1的子串与s2的子串比较*/

    for (p=0;p<j)&&(3);p++);

    if ((4)) /*如果两子串相同*/

    {for(p=0);p<j;p++} /*输出子串*/

    printf ("%c",s2[k+p]);

    printf ("\n");

    count++;/*计数增1 */

    }

    }

    }

    if (count>0) break;

    *sublen=(count>0)?(5):0;

    return count;

    }


    正确答案:(1)k+j (2)i+j-1 (3)s1[i+P]==s2[k+P] (4)P==j或p>=j (5)j
    (1)k+j (2)i+j-1 (3)s1[i+P]==s2[k+P] (4)P==j或p>=j (5)j

  • 第2题:

    对于求取两个长度为n的字符串的最长公共子序列(LCS)问题,利用(24)策略可以有效地避免子串最长公共子序列的重复计算,得到时间复杂度为O(n2)的正确算法。串 <1,0,0,1,O,1,0,1>和<0,1,0,1,1,0,1,1>的最长公共子序列的长度为(25)。

    A.分治

    B.贪心

    C.动态规划

    D.分支—限界


    正确答案:C

  • 第3题:

    阅读以下说明和流程图,填补流程图中的空缺,将解答填入答题纸的对应栏内。
    [说明]
    下面流程图的功能是:在给定的两个字符串中查找最长的公共子串,输出该公共子串的长度L及其在各字符串中的起始位置(L=0时不存在公共字串)。例如,字符串"The light is not bright tonight"与"Tonight the light is not bright"的最长公共子串为"he light is not bright",长度为22,起始位置分别为2和10。
    设A[1:M]表示由M个字符A[1],A[2],…,A[M]依次组成的字符串;B[1:N]表示由N个字符B[1],B[2],…,B[N]依次组成的字符串,M≥N≥1。
    本流程图采用的算法是:从最大可能的公共子串长度值开始逐步递减,在A、B字符串中查找是否存在长度为L的公共子串,即在A、B字符串中分别顺序取出长度为L的子串后,调用过程判断两个长度为L的指定字符串是否完全相同(该过程的流程略)。
    [流程图]


    答案:
    解析:
    N或rnin(M,N)
    M-L+1
    N-L+1
    L-1
    L,I,J

    【解析】

    本题考查对算法流程图的理解和绘制能力。这是程序员必须具有的技能。
    本题的算法可用来检查某论文是否有大段抄袭了另一论文。"The light is not bright tonight"是著名的英语绕口令,它与"Tonight the light is not bright"大同小异。
    由于字符串A和B的长度分别为M和N,而且M≥N≥1,所以它们的公共子串长度L必然小于或等于N。题中采用的算法是,从最大可能的公共子串长度值L开始逐步递减,在A、B字符串中查找是否存在长度为L的公共子串。因此,初始时,应将min(M,N)送L,或直接将N送L。(1)处应填写N或min(M,N),或其他等价形式。
    对每个可能的L值,为查看A、B串中是否存在长度为L的公共子串,显然需要执行双重循环。A串中,长度为L的子串起始下标可以从l开始直到M-L+1(可以用实例来检查其正确性);B串中,长度为L的子串起始下标可以从1开始直到N-L+1。因此双重循环的始值和终值就可以这样确定,即(2)处应填M-L+1,或等价形式;(3)处应填N-L+1或等价形式(注意循环的终值应是最右端子串的下标起始值)。
    A串中从下标I开始长度为L的子串可以描述为A[I:I+L-1];B串中从下标J开始长度为L的子串可以描述为A[J:J+L-1]。因此,双重循环体内,需要比较这两个子串(题中采用调用专门的函数过程或子程序来实现)。
    如果这两个子串比较的结果相同,那么就已经发现了A、B串中最大长度为L的公共子串,此时,应该输出公共子串的长度值L、在A串中的起始下标I、在B串中的起始下标J。因此,(5)处应填L,I,J(可不计顺序)。
    如果这两个子串比较的结果不匹配,那么就需要继续执行循环。如果直到循环结束仍然没有发现匹配子串时,就需要将L减少1((4)处填L-1或其等价形式)。只要L非0,则还可以继续对新的L值执行双重循环。如果直到L=0,仍没有发现子串匹配,则表示A、B两串没有公共子串。

  • 第4题:

    阅读下列说明和C代码,回答问题1至问题3,将解答写在答题纸的对应栏内。
    【说明】 计算两个字符串x和y的最长公共子串(Longest Common Substring)。 假设字符串x和字符串y的长度分别为m和n,用数组c的元素c[i][j]记录x中前i个字符和y中前j个字符的最长公共子串的长度。c[i][j]满足最优子结构,其递归定义为:




    计算所有c[i][j](0 ≤i ≤ m,0 ≤j ≤ n)的值,值最大的c[i][j]即为字符串x和y的最长公共子串的长度。根据该长度即i和j,确定一个最长公共子串。【C代码】(1)常量和变量说明 x,y:长度分别为m和n的字符串 c[i][j]:记录x中前i个字符和y中前j个字符的最长公共子串的长度 max:x和y的最长公共子串的长度 maxi, maXj:分别表示x和y的某个最长公共子串的最后一个字符在x和y中的位置(序号) (2)C程序#include
    < stdio.h>#include
    < string.h>int c[50][50];int maxi;int maxj;int lcs(char
    *x, int m, char *y, int n) { int i, j; int max= 0; maxi= 0; maxj = 0;for ( i=0;
    i < =m ; i++) c[i][0] = 0;for (i =1;
    i < = n; i++) c[0][i]=0;for (i =1;
    i < = m; i++) { for (j=1; j < = n; j++) { if (
    (1) ) {c[i][j] = c[i
    -1][j -1] + 1;if(max < c[i][j])
    { (2)
    ; maxi = i; maxj =j; }}else (3)
    ; } } return max;}void
    printLCS(int max, char *x) { int i= 0; if (max == 0) return; for (
    (4) ; i < maxi; i++)printf("%c",x[i]);}void main( ){ char* x= "ABCADAB"; char*y= "BDCABA"; int max= 0; int m = strlen(x); int n = strlen(y); max=lcs(x,m,y,n); printLCS(max , x);}
    【问题1】(8分)
    根据以上说明和C代码,填充C代码中的空(1)~(4)。
    【问题2】(4分)
    根据题干说明和以上C代码,算法采用了 (5) 设计策略。
    分析时间复杂度为 (6) (用O符号表示)。
    【问题3】(3分)
    根据题干说明和以上C代码,输入字符串x= "ABCADAB’,'y="BDCABA",则输出为 (7) 。


    答案:
    解析:
    【问题1】(8分)答案:(1)x[i-1]= =y[j-1] (2)max=c[i][j](3)c[i][j]=0 (4)i=maxi-max

    【问题2】(4分)答案:动态规划、 O(m×n)或O(mn)

    【问题3】(3分)答案:AB根据题干和C代码,计算出下表的值。



    最大值为2。在计算过程中,我们记录第一个最大值,即表中阴影部分元素,因此得到最长公共子串为AB。

  • 第5题:

    在求解某问题时,经过分析发现该问题具有最优子结构性质,若定义问题的解空间,以深度优先的方式搜索解空间,则采用( )算法设计策略。

    A.动态规划
    B.贪心
    C.回溯
    D.分支限界

    答案:C
    解析:
    分治法的设计思想是将一个难以直接解决的大问题分解成一些规模较少的相同问题以便各个击破,分而治之。
    动态规划法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是独立的。若用分治法来解这类问题,则相同的子问题会被求解多次,以至于最后解决原问题需要耗费指数级时间。
    贪心法经常用于解决最优化问题,但他的最优往往是从局部最优来考虑的,每一步都选最优的方案,但这种方案不一定能得到整体上的最优解。
    回溯法是一种既带有系统性又带有跳跃性的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根节点出发搜索解空间树。
    题目描述中提到,需要解决的问题具有最优子结构性质,且求解过程中子问题被重复求解,这种情况下如果采用分治法,效率会很低,所以应采用动态规划法。而“以深度优先的方式搜索解空间”则明显是在采用回溯法。

  • 第6题:

    实现最长公共子序列利用的算法是()。

    • A、分治策略
    • B、动态规划法
    • C、贪心法
    • D、回溯法

    正确答案:B

  • 第7题:

    给定一个由n个数组成的序列,要求该序列的最长单调上升子序列,请设计对应的算法并分析其时间复杂度,如果时间复杂度劣于O(nlogn)的,将其优化为O(nlogn)时间复杂度的算法。


    正确答案: 假设当前已求出m[1..i-1],当前保留的状态集合为S,下面计算m[i]。
    1、若存在状态k∈S,使得x[k]=x[i],则状态m[i]必定不需保留,不必计算。因为,不妨设m[i]=m[j]+1,则x[j] 2、否则,m[i]=1+max{m[j]|x[j] 3、若2成立,则我们往S中增加了一个状态,为了保持S的性质,我们要对S进行维护,若存在状态k∈S,使得m[i]=m[k],则我们有x[i]x[i],j∈S}。于是状态k应从S中删去。
    从性质D和算法描述可以发现,S实际上是以x值为关键字(也是以m值为关键字)的有序集合。若使用平衡树实现有序集合S,则该算法的时间复杂度为O(n*logn)。(每个状态转移的状态数仅为O(1),而每次状态转移的时间变为O(logn))。

  • 第8题:

    最长公共子序列算法利用的算法是()。

    • A、分支界限法
    • B、动态规划法
    • C、贪心法
    • D、回溯法

    正确答案:B

  • 第9题:

    将一个较大规模的问题分解为较小规模的子问题,求解子问题、合并子问题的解得到整个问题的解的算法是()。

    • A、贪心法
    • B、分治法
    • C、动态规划法
    • D、回朔法

    正确答案:B

  • 第10题:

    单选题
    已知序列X={x1,x2,…,xm},序列Y={y1,y2,…,yn},使用动态规划算法求解序列X和Y的最长公共子序列,其最坏时间复杂度为()。
    A

    O(m*n)

    B

    O(m+n)

    C

    O(m*2n

    D

    O(n*2m


    正确答案: A
    解析: 暂无解析

  • 第11题:

    问答题
    给定一个由n个数组成的序列,要求该序列的最长单调上升子序列,请设计对应的算法并分析其时间复杂度,如果时间复杂度劣于O(nlogn)的,将其优化为O(nlogn)时间复杂度的算法。

    正确答案: 假设当前已求出m[1..i-1],当前保留的状态集合为S,下面计算m[i]。
    1、若存在状态k∈S,使得x[k]=x[i],则状态m[i]必定不需保留,不必计算。因为,不妨设m[i]=m[j]+1,则x[j] 2、否则,m[i]=1+max{m[j],x[j] 3、若2成立,则我们往S中增加了一个状态,为了保持S的性质,我们要对S进行维护,若存在状态k∈S,使得m[i]=m[k],则我们有x[i]x[i],j∈S}。于是状态k应从S中删去。
    从性质D和算法描述可以发现,S实际上是以x值为关键字(也是以m值为关键字)的有序集合。若使用平衡树实现有序集合S,则该算法的时间复杂度为O(n*logn)。(每个状态转移的状态数仅为O(1),而每次状态转移的时间变为O(logn))。
    解析: 暂无解析

  • 第12题:

    填空题
    两个字符串S1和S2的长度分别为m和n,求这两个字符串最大共同子串的时间复杂度为T(m,n),这最优的时间复杂度为()。

    正确答案: O(m*n)
    解析: 暂无解析

  • 第13题:

    对于求取两个长度为n的字符串的最长公共子序列问题,利用(41)策略可以有效地避免子串最长公共子序列的重复计算,得到时间复杂度为O(n2)的正确算法。

    A.贪心

    B.分治

    C.分支-限界

    D.动态规划


    正确答案:D
    解析:对于求取两个长度为n的字符串的最长公共子序列(LCS)问题,是利用动态规划策略解决的经典问题之一。利用动态规划策略求解该问题时可以通过查表得到已经计算出的子串的最长公共子序列,从而避免重复计算。例如,利用动态规划算法可以得到串1,0,0,1,0,1,0,1>和0,1,0,1,1,0,1,1>的最长公共子序列的长度为6,如“101011”。

  • 第14题:

    阅读下列说明和C代码,回答问题l至问题3.将解答写在答题纸的对应栏内。

    【说明】

    计算一个整数数组a的最长递增子序列长度的方法描述如下:

    假设数组a的长度为n,用数组b的元素b[i]记录以a[i](0≤i<n)为结尾元素的最长

    递增子序列的长度,则数组a的最长递增子序列的长度为器;其中b[i]满足最优子结构,可递归定义为:

    【c代码】

    下面是算法的c语言实现。

    (1)常量和变量说明

    a:长度为n的整数数组,待求其最长递增子序列

    b:长度为n的数组,b[i]记录以a[i](0≤i<n)为结尾元素的最长递增子序列的长度,

    其中0≤i<n

    len:最长递增子序列的长度

    i.j:循环变量

    temp,临时变量

    (2)C程序

    include <stdio . h>

    int maxL (int *b. int n) {

    int i. temp =0;

    For(i = 0; i < n; i++){

    if (b[i] > temp )

    Temp= b[i];

    }

    Return temp;

    【问题l】(8分)

    根据说明和C代码,填充C代码中的空(1)~(4)。

    【问题2】(4分)

    根据说明和C代码,算法采用了(5)设计策略,时间复杂度为(6)(用O符号表示)。

    【问题3】(3分)

    已知数组a={3,10,5,15,6,8},根据说明和C代码,给出数组b的元素值。


    正确答案:
    本题考查算法设计与分析以及用C程序设计语言来实现算法的能力。此类题目要求考生认真阅读题目对问题的描述,理解算法思想,并会用C程序设计语言来实现。【问题1】根据题干描述,用一个数组b来记录数组a每个子数组的最长递增子序列的长度,即b[i]记录a[0..i]的最长递增子序列的长度。首先,只有一个元素的数组的最长递增子序列的长度为1,即给b[0]直接赋值1。因此,空(1)处填写“b[0]=1”。两重for循环中,第一重是从a数组的第二个元素开始,考虑每个子数组a[0....II]的最长递增子序列的长度,第二重是具体的计算过程。考虑子数组a[0..I],其最长递增于序列的长度应该等于子数组a[O.i-l]中的比元素a[i]小的元素的最长递增子序列的长度加1,当然,可能存在多个元素比元素a[i]小,那么存在多个最长递增子序列的长度,此时,取最大者。因此,空处填写j<i”,即考虑子数组a[O...i-l]。空(3)处填写“a[j]<=a[i]”,要求元素值小于等于a[i]而且目前的长度应该小于当前考虑的子数组的最长子序列长度。空(4)处填写“b[i]=len+1”。简单的说,程序是根据题干给出的公式来实现的。另外,计算的过程不是采用递归的方式,而是以一种自底向上的方式进行的【问题2】从题干说明和C程序来看,这是一个最优化问题,而且问题具有最优子结构,一个序列的最长递增子序列由其子序列的最长递增子序列构成。在计算过程中采用了自底向上的方式来进行,这具有典型的动态规划特征。因此采用的是动态规划设计策略。C程序中,有两重for循环,因此时间复杂度为。【问题3】输入数组为数组a={3.10,5,15,6,8},很容易得到,子数组a[0...0],a[0..1].…,a[0....5]的最长递增子序列的长度分别为l,2,2,3,3,4,因此答案为b={I,2,2,3,4}。该题可以根据题干说明、C代码来计算。由于输入很简单,答案也可以从输入直接许算出来。试题四参考答案【问题1】(1)b[0]=I(2)j<i(3)a[j]<=a[i](4)b[i]=len+1【问题2】(5)动态规划(6)【问题3】b={1,2,2,3,3,4}

  • 第15题:

    求解两个长度为n的序列X和Y的一个最长公共子序列(如序列ABCBDAB和BDCABA的一个最长公共子序列为BCBA)可以采用多种计算方法。如可以采用蛮力法,对X的每一个子序列,判断其是否也是Y的子序列,最后求出最长的即可,该方法的时间复杂度为( )。经分析发现该问题具有最优子结构,可以定义序列长度分别为i和j的两个序列X和Y的最长公共子序列的长度为c[i,j],如下式所示。



    采用自底向上的方法实现该算法,则时间复杂度为(请作答此空)

    A.O(n^2)
    B.O(n^21gn)
    C.O(n^3)
    D.O(n2^n)

    答案:A
    解析:
    蛮力法,对X的每一个子序列,判断是否也是Y的子序列,其中,长度为n的序列X共有2^n个子序列,判断其是否是Y的子序列时间是n,因此是n*2^n;采用动态规划法自底向上实现时,根据递归公式,实际是关于i和j的两重循环,因此时间复杂度是n^2.

  • 第16题:

    采用贪心算法保证能求得最优解的问题是( )

    A.0-1背包
    B.矩阵连乘
    C.最长公共子序列
    D.邻分(分数)背包

    答案:D
    解析:
    动态规划算法适合解决0-1背包问题,贪心法适合解决部分背包(邻分(分数)背包)问题。

  • 第17题:

    在求解某问题时,经过分析发现该问题具有最优子结构性质,求解过程中子问题被重复求解,则采用( )算法设计策略

    A.分治
    B.动态规划
    C.贪心
    D.回溯

    答案:B
    解析:
    分治法的设计思想是将一个难以直接解决的大问题分解成一些规模较少的相同问题以便各个击破,分而治之。
    动态规划法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是独立的。若用分治法来解这类问题,则相同的子问题会被求解多次,以至于最后解决原问题需要耗费指数级时间。
    贪心法经常用于解决最优化问题,但他的最优往往是从局部最优来考虑的,每一步都选最优的方案,但这种方案不一定能得到整体上的最优解。回溯法是一种既带有系统性又带有跳跃性的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根节点出发搜索解空间树。
    题目描述中提到,需要解决的问题具有最优子结构性质,且求解过程中子问题被重复求解,这种情况下如果采用分治法,效率会很低,所以应采用动态规划法。而“以深度优先的方式搜索解空间”则明显是在采用回溯法。

  • 第18题:

    已知序列X={x1,x2,…,xm},序列Y={y1,y2,…,yn},使用动态规划算法求解序列X和Y的最长公共子序列,其最坏时间复杂度为()。

    • A、O(m*n)
    • B、O(m+n)
    • C、O(m*2n
    • D、O(n*2m

    正确答案:A

  • 第19题:

    两个字符串S1和S2的长度分别为m和n,求这两个字符串最大共同子串的时间复杂度为T(m,n),这最优的时间复杂度为()。


    正确答案:O(m*n)

  • 第20题:

    把大问题分解成子问题,且子问题有大量重合的问题求解,较好的算法是()。

    • A、贪心法
    • B、分治法
    • C、动态规划法
    • D、回朔法

    正确答案:C

  • 第21题:

    单选题
    最长公共子序列算法利用的算法是()。
    A

    分支界限法

    B

    动态规划法

    C

    贪心法

    D

    回溯法


    正确答案: B
    解析: 暂无解析

  • 第22题:

    单选题
    实现最长公共子序列利用的算法是()。
    A

    分治策略

    B

    动态规划法

    C

    贪心法

    D

    回溯法


    正确答案: A
    解析: 暂无解析

  • 第23题:

    单选题
    将一个较大规模的问题分解为较小规模的子问题,求解子问题、合并子问题的解得到整个问题的解的算法是()。
    A

    贪心法

    B

    分治法

    C

    动态规划法

    D

    回朔法


    正确答案: A
    解析: 暂无解析