HZAU oj 1015(LCS)

来源:互联网 发布:杭州一知智能科技官网 编辑:程序博客网 时间:2024/06/05 06:27

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

abxccdefabcxcdef3abccdefabcdef3

Sample Output

46

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;}


0 0