DNA Sequences,dp

本文介绍了一道关于最长公共子序列的算法题,题目要求找到两个字符串的最长公共子序列,且子序列中每段连续子串长度需大于等于K。文章提供了详细的解析过程及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题题目看完之后,完全没思路,后来看了yobobobo的代码,还是不懂,照着敲了一遍,才算理解过来,本来都不好意思发题解的,不过这道题感觉出处不好找,怕以后回来找不到题目了,所以记录一下。

题目如下:

Thomas, a computer scientist that works with DNA sequences, needs to compute longest common subsequences of given pairs of strings. Consider an alphabet Σ of letters and a word w=a1a2 …ar, where ai ∈ Σ, for i = 1, 2, …,r. A subsequence of w is a wordx=ai1ai2 …ais such that 1 ≤ i1 < i2 < … < is ≤ r. Subsequence x is a segment of w if ij+1=ij + 1, for j = 1,2, …,s -1. For example the word ove is a segment of the word lovely, whereas the word loly is a subsequence of lovely, but not a segment.

A word is a common subsequence of two words w1 and w2 if it is a subsequence of each of the two words. A longest common subsequence of w1 and w2 is a common subsequence of w1 and w2 having the largest possible length. For example, consider the wordsw1=lovxxelyxxxxx and w2=xxxxxxxlovely. The words w3=lovely and w4=xxxxxxx, the latter of length 7, are both common subsequences of w1 and w2. In fact, w4 is their longest common subsequence. Notice that the empty word, of length zero, is always a common subsequence, although not necessarily the longest.

In the case of Thomas, there is an extra requirement: the subsequence must be formed from common segments having length K or more. For example, if Thomas decides that K=3, then he considers lovely to be an acceptable common subsequence of lovxxelyxxxxx andxxxxxxxlovely, whereas xxxxxxx, which has length 7 and is also a common subsequence, is not acceptable. Can you help Thomas?

Input

The input contains several test cases. The first line of a test case contains an integer K representing the minimum length of common segments, where 1 ≤ K ≤ 100. The next two lines contain each a string on lowercase letters from the regular alphabet of 26 letters. The length l of each string satisfies the inequality 1 ≤ l ≤ 103. There are no spaces on any line in the input. The end of the input is indicated by a line containing a zero.

 

Output

For each test case in the input, your program must print a single line, containing the length of the longest subsequence formed by consecutive segments of length at least K from both strings. If no such common subsequence of length greater than zero exists, then 0must be printed.

Example

Input: 3
lovxxelyxxxxx
xxxxxxxlovely
1
lovxxelyxxxxx
xxxxxxxlovely
3
lovxxxelxyxxxx
xxxlovelyxxxxxxx
4
lovxxxelyxxx
xxxxxxlovely
0 Output: 6
7
10
0

题目挺好理解的,是最长公共子序列的加强版,不过就是要求找到的最长公共子序列同时还满足每一小段子序列的长度都大于k。

这题因为有多组数据,所以n*n*k会超时,只能n*n过。好难想。。。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define INF 200000000
int match[1005][1005],dp[1005][1005],len1,len2;
char s1[1005],s2[1005];
int max(int a,int b)
{
    return a>b?a:b;
}
int main()
{
    int kk,i,j,k,l;
    while(scanf("%d",&kk)!=EOF&&kk!=0)
    {
        scanf("%s%s",s1+1,s2+1);
        len1=strlen(s1+1);
        len2=strlen(s2+1);
        match[0][0]=0;
        for(i=1;i<=len1;i++)
            for(j=1;j<=len2;j++)
        {
            if(s1[i]==s2[j])
                match[i][j]=match[i-1][j-1]+1;
            else
                match[i][j]=0;
        }
        for(i=1;i<=len1;i++)
            for(j=1;j<=len2;j++)
        {
            dp[i][j]=0;
            dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
            if(match[i][j]>=kk)
                dp[i][j]=max(dp[i][j],dp[i-kk][j-kk]+kk);
            if(match[i][j]>kk)
                dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
        }
        printf("%d\n",dp[len1][len2]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值