博客
关于我
【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 deadlock found when trying to get lock暴力解决
    查看>>
    MuseTalk如何生成高质量视频(使用技巧)
    查看>>
    mutiplemap 总结
    查看>>
    MySQL DELETE 表别名问题
    查看>>
    MySQL Error Handling in Stored Procedures---转载
    查看>>
    MVC 区域功能
    查看>>
    MySQL FEDERATED 提示
    查看>>
    mysql generic安装_MySQL 5.6 Generic Binary安装与配置_MySQL
    查看>>
    Mysql group by
    查看>>
    MySQL I 有福啦,窗口函数大大提高了取数的效率!
    查看>>
    mysql id自动增长 初始值 Mysql重置auto_increment初始值
    查看>>
    MySQL in 太多过慢的 3 种解决方案
    查看>>
    MySQL InnoDB 三大文件日志,看完秒懂
    查看>>
    Mysql InnoDB 数据更新导致锁表
    查看>>
    Mysql Innodb 锁机制
    查看>>
    MySQL InnoDB中意向锁的作用及原理探
    查看>>
    MySQL InnoDB事务隔离级别与锁机制深入解析
    查看>>
    Mysql InnoDB存储引擎 —— 数据页
    查看>>
    Mysql InnoDB存储引擎中的checkpoint技术
    查看>>
    Mysql InnoDB存储引擎中缓冲池Buffer Pool、Redo Log、Bin Log、Undo Log、Channge Buffer
    查看>>