博客
关于我
【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/

    你可能感兴趣的文章
    Python scrapy 常见问题及解决 【遇到的坑】
    查看>>
    Python Seborn热图数据的动态更新
    查看>>
    Python Seborn绘制空白直方图
    查看>>
    Python Selenium - 获取href值
    查看>>
    Python Selenium实现自动化测试及Chrome驱动使用!
    查看>>
    Python Selenium搭建UI自动化测试框架
    查看>>
    Python Selenium模块详解
    查看>>
    Python selenium爬取影评生成词云图
    查看>>
    python selenium自动化测试报告
    查看>>
    Python selenium自动化测试框架实战 —— 登录测试案例
    查看>>
    Python Selenium设计模式 —— POM
    查看>>
    Python Serial:如何使用 read 或 readline 函数一次读取多个字符
    查看>>
    Python set([]) 如何检查两个对象是否相等?一个对象需要定义哪些方法来自定义它?
    查看>>
    Python setup.py:数据文件无法复制目录:不存在或不是常规文件
    查看>>
    Python setuptools sdist:仅安装版本化文件
    查看>>
    Python Shell下使用matplotlib
    查看>>
    Python Slice How-to,我知道Python Slice,但我怎么才能使用内置的Slice对象呢?
    查看>>
    python socket分包发送数据
    查看>>
    python socket模块_Python socket模块实现TCP服务端客户端
    查看>>
    Python SOCKS5代理客户端HTTPS
    查看>>