• GDKOI2003 最大公共子串


    AOJ链接:最大公共子串

    这道题求多个字符串的最大公共序列(非连续)的长度,题目中说明了所有串的乘积不超过30000;

    题解将状态记录在一个长度为30000的数组中,使用类似编码的方式(我的理解)进行存取;

    和算法导论上对LCS的解法不大一样(递归而不是递推,计算量会少一些),仍然是动态规划的思想;

    0MS,学习了。

    下面的代码是看懂了书上的后,自己写的;

    起先觉得第47、48行的恢复多余,后来发现并不是:包含回溯的过程,需要恢复原来的下标。

     1 # include <stdio.h>
    2 # include <string.h>
    3
    4 char str[102][102];
    5 int c[30005];
    6 int tmp[102];
    7 int len[102];
    8
    9 int get(int n, int *x);
    10
    11 int main()
    12 {
    13 int T, N, i;
    14
    15 scanf("%d", &T);
    16 while (T--)
    17 {
    18 scanf("%d", &N);
    19 memset(c, 0xff, sizeof(c));
    20 for (i = 1; i <= N; ++i)
    21 {
    22 scanf("%s", str[i]);
    23 tmp[i] = len[i] = (int)strlen(str[i]);
    24 }
    25 printf("%d\n", get(N, tmp));
    26 }
    27
    28 return 0;
    29 }
    30
    31 int get(int n, int *x)
    32 {
    33 int i, j, index, ret, rem;
    34
    35 for (i = 1; i <= n; ++i)
    36 if (x[i] == 0) return 0;
    37 for (i = n-1, index = x[n]-1; i >= 1; --i)
    38 index = index*len[i] + x[i]-1;
    39 if (c[index] >= 0) return c[index];
    40 for (i = 2; i <= n; ++i)
    41 if (str[1][x[1]-1] != str[i][x[i]-1]) break;
    42 if (i > n)
    43 {
    44 for (j = 1; j <= n; ++j)
    45 --x[j];
    46 ret = get(n, x) + 1;
    47 for (j = 1; j <= n; ++j)
    48 ++x[j];
    49 } else
    50 {
    51 ret = 0;
    52 for (j = 1; j <= n; ++j)
    53 {
    54 --x[j];
    55 rem = get(n, x);
    56 if (rem > ret) ret = rem;
    57 ++x[j];
    58 }
    59 }
    60 c[index] = ret;
    61 return ret;
    62 }



  • 相关阅读:
    Spring ContextLoaderListener
    判断整数是否是对称数
    jstl缺包时的报错
    Spring初始化日志
    C# 网络编程之最简单浏览器实现
    Java实现 蓝桥杯 算法训练 Anagrams问题
    Java实现 蓝桥杯 算法训练 出现次数最多的整数
    Java实现 蓝桥杯 算法训练 出现次数最多的整数
    Java实现 蓝桥杯 算法训练 字串统计
    Java实现 蓝桥杯 算法训练 字串统计
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2422443.html
Copyright © 2020-2023  润新知