【动态规划】之最长公共子序列长度(难度:1星)

来源:互联网 发布:mac电脑磁盘在哪里 编辑:程序博客网 时间:2024/06/04 19:53

#include <stdio.h>/** * 原题: * 给定两个字符串ST,求出这两个字符串的最长公共子序列的长度 * 例如X={A,B,C,B,D,A,B}Y={B,D,C,A,B,A} * 则它们的lcs4 ({B,C,B,A}{B,D,A,B})。求出一个即可。 */#define MAX(x,y) (x>y?x:y)#define SL 7#define TL 6static char s[SL+2] = " ABCBDAB";static char t[TL+2] = " BDCABAB";/** * 思路: * 设置子问题:s的前i个字符组成的字符串与t的前j个字符组成的字符串的最大公共子序列长度 * 找出边界:显然ij等于0,最大公共子序列长度为0 *///解法1:递归int solve_1(int i, int j){    if (i == 0 || j == 0)        return 0;    if (s[i] == t[j])        return MAX(solve_1(i-1, j-1) + 1, MAX(solve_1(i-1, j), solve_1(i, j-1)));    return MAX(solve_1(i-1, j), solve_1(i, j-1));}//解法2:递归+记忆数组static int memo[SL+1][TL+1];int solve_2(int i, int j){    if (i == 0 || j == 0)        return memo[i][j] = 0;    if (memo[i][j] > -1)        return memo[i][j];    if (s[i] == t[j])        return memo[i][j] = MAX(solve_2(i-1, j-1) + 1, MAX(solve_2(i-1, j), solve_2(i, j-1)));    return memo[i][j] = MAX(solve_2(i-1, j), solve_2(i, j-1));}//解法3:递推static int maxLen[SL+1][TL+1];int solve_3(){    for (int i = 1; i <= SL; ++i) {        for (int j = 1; j <= TL; ++j) {            if (s[i] == t[j])                maxLen[i][j] = MAX(maxLen[i-1][j-1] + 1, MAX(maxLen[i-1][j], maxLen[i][j-1]));            else                maxLen[i][j] = MAX(maxLen[i-1][j], maxLen[i][j-1]);        }    }    return maxLen[SL][TL];}int main() {    printf("solve_1:%d\n", solve_1(SL, TL));    for (int i = 0; i <= SL; ++i) {        for (int j = 0; j <= TL ; ++j) {            memo[i][j] = -1;        }    }    printf("solve_2:%d\n", solve_2(SL, TL));//    for (int i = 0; i <= SL; ++i) {//        for (int j = 0; j <= TL ; ++j) {//            printf("%d\t", memo[i][j]);//        }//        printf("\n");//    }    printf("solve_3:%d\n", solve_3());//    for (int i = 0; i <= SL; ++i) {//        for (int j = 0; j <= TL ; ++j) {//            printf("%d\t", maxLen[i][j]);//        }//        printf("\n");//    }    return 0;}

运行结果:

solve_1:4solve_2:4solve_3:4




原创粉丝点击