博客
关于我
【GDOI2018模拟7.10】C
阅读量:635 次
发布时间:2019-03-14

本文共 2462 字,大约阅读时间需要 8 分钟。

为了解决这个问题,我们需要计算两个字符串X和Y的最长公共子序列的长度,并根据这个长度计算另一个值f[n][m]。这个问题可以通过动态规划来解决。

方法思路

  • 问题分析

    • 我们需要计算两个字符串X和Y的最长公共子序列的长度,记为c[i][j]。
    • 然后,我们需要计算f[i][j],即在X的前i个字符中,有多少个长度为c[i][j]的子序列在Y的前j个字符中也出现了。
  • 动态规划状态定义

    • c[i][j] 表示X的前i个字符和Y的前j个字符的最长公共子序列的长度。
    • f[i][j] 表示在X的前i个字符中,有多少个长度为c[i][j]的子序列在Y的前j个字符中也出现了。
  • 状态转移方程

    • 如果X[i]等于Y[j],则c[i][j] = c[i-1][j-1] + 1,并且f[i][j] = f[i-1][j-1] + f[i-1][j]。
    • 否则,c[i][j] = max(c[i-1][j], c[i][j-1]),并且f[i][j] = f[i-1][j] + f[i-1][j]。
  • 优化技巧

    • 预处理Y数组,记录每个字符的最后出现位置,以便快速查找。
  • 解决代码

    #include 
    #include
    #include
    using namespace std;const int MOD = 1e9 + 7;char a[1001], b[1001];int c[1001][1001], f[1001][1001], pos[1001][1001];int al, bl;int main() { memset(c, 0, sizeof(c)); memset(f, 0, sizeof(f)); scanf("%s%s", a, b); al = strlen(a); bl = strlen(b); // 预处理last_pos数组,记录Y中每个字符的最后出现位置 int last_pos[256] = {0}; for (int j = 0; j < bl; ++j) { char ch = b[j]; last_pos[ch] = j; } // 初始化pos数组 for (int i = 0; i < al; ++i) { for (int j = 0; j < bl; ++j) { pos[i][j] = -1; } } for (int i = 0; i < al; ++i) { for (int j = 0; j < bl; ++j) { if (a[i] == b[j]) { pos[i][j] = j; } } } for (int i = 0; i < al; ++i) { for (int j = 0; j < bl; ++j) { if (i == 0 || j == 0) { c[i][j] = 0; f[i][j] = 0; continue; } if (a[i] == b[j]) { if (c[i-1][j-1] + 1 > c[i][j-1] && c[i-1][j-1] + 1 > c[i-1][j]) { c[i][j] = c[i-1][j-1] + 1; } else { c[i][j] = max(c[i-1][j], c[i][j-1]); } if (c[i][j] == c[i-1][j]) { f[i][j] = (f[i][j] + f[i-1][j]) % MOD; } if (a[i] == b[j]) { int p = last_pos[b[j]]; if (c[i-1][p] + 1 == c[i][j]) { f[i][j] = (f[i][j] + f[i-1][p]) % MOD; } } } else { c[i][j] = max(c[i-1][j], c[i][j-1]); f[i][j] = (f[i-1][j] + f[i][j-1]) % MOD; } } } cout << f[al][bl] << endl; return 0;}

    代码解释

  • 初始化

    • 初始化c和f数组,分别表示最长公共子序列长度和对应的子序列数量。
    • 使用last_pos数组记录Y中每个字符的最后出现位置,用于快速查找。
  • 预处理

    • 填充pos数组,记录每个字符在X和Y中的位置。
  • 动态规划

    • 遍历每个字符位置,更新c和f数组。
    • 当字符匹配时,更新c为c[i-1][j-1] + 1,并根据匹配情况更新f。
    • 当字符不匹配时,更新c为最大值,并累加前缀结果。
  • 输出结果

    • 打印最终的f值,即为答案。
  • 转载地址:http://dvvoz.baihongyu.com/

    你可能感兴趣的文章
    MySQL - 4种基本索引、聚簇索引和非聚索引、索引失效情况、SQL 优化
    查看>>
    MySQL - ERROR 1406
    查看>>
    mysql - 视图
    查看>>
    MySQL - 解读MySQL事务与锁机制
    查看>>
    mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
    查看>>
    mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
    查看>>
    mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
    查看>>
    MySQL Binlog 日志监听与 Spring 集成实战
    查看>>
    multi-angle cosine and sines
    查看>>
    Mysql Can't connect to MySQL server
    查看>>
    mysql case when 乱码_Mysql CASE WHEN 用法
    查看>>
    Multicast1
    查看>>
    MySQL Cluster 7.0.36 发布
    查看>>
    Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
    查看>>
    multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
    查看>>
    mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
    查看>>
    Multiple websites on single instance of IIS
    查看>>
    mysql CONCAT()函数拼接有NULL
    查看>>
    multiprocessing.Manager 嵌套共享对象不适用于队列
    查看>>
    multiprocessing.pool.map 和带有两个参数的函数
    查看>>