HZAU oj 1015(LCS)

1015: LCS

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 58   Solved: 26
[ Submit][ Status][ Web Board]

Description

   Giving two strings consists of only lowercase letters, find the LCS(Longest Common Subsequence) whose all partition are not less than k in length.

Input

There are multiple test cases. In each test case, each of the first two lines is a string(length is less than 2100). The third line is a positive integer k. The input will end by EOF.

Output

    For each test case, output the length of the two strings’ LCS.

Sample Input

abxccdef
abcxcdef
3
abccdef
abcdef
3

Sample Output

4
6

HINT



   In the first test case, the answer is:


      abxccdef


      abcxcdef


    The length is 4.


   In the second test case, the answer is:


      abccdef


      abc def


   The length is 6


题目链接:http://acm.hzau.edu.cn/problem.php?id=1015


题意:求最长公共子序列,不过对序列还要加上每个部分长度要大于k的条件。即当且仅当子序列是连续的不小于k的子串时,其算符合条件的子序列。


解题思路:

动规。只需对经典的LCS算法做稍微的改动。

首先,需要记录两个序列相同的连续子串部分。rec[i, j]表示两个字符串a和b的以ai和bj结尾的两个连续子串的相同数目

然后,即进入动规部分。

dp[i, j]表示ai和bj的前缀中最大的符合条件的LCS。则有状态转移方程:

dp[i, j] = max(dp[i-1, j-1]+1, dp[i-k][j-k]+k), ai=bj and rec[i, j] >= k

dp[i, j] = max(dp[i-1, j], dp[i, j-1]) ai ≠ bj and rec[i, j] >= k

代码:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
 
char a[2300], b[2300];
int dp[2300][2300], tmp[2300][2300];
 
int main(){
    int k;
    while(scanf("%s%s%d", a+1, b+1, &k) != EOF){
        memset(dp, 0, sizeof dp);
        memset(tmp, 0, sizeof tmp);
        int l1 = strlen(a+1), l2 = strlen(b+1);
        if(k > min(l1, l2)){
            printf("0\n");
            continue;
        }
        for(int i = 1; i <= l1; i++){
            for(int j = 1; j <= l2; j++){
                if(a[i] == b[j]){
                     dp[i][j] = dp[i-1][j-1] + 1;
                }
            }
        }
        for(int i = 1; i <= l1; i++){
            for(int j = 1; j <= l2; j++){
                if(dp[i][j] >= k){
                    tmp[i][j] = max(tmp[i-1][j-1]+1, tmp[i-k][j-k] + k);
                }
                else tmp[i][j] = max(tmp[i-1][j],  tmp[i][j-1]);
            }
        }
        printf("%d\n", tmp[l1][l2]);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/Mad_boys/article/details/51448674
OJ
LCS