博客
关于我
【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 字符串显示中文_Python字符串开头的b"、u"、r"与中文乱码
    查看>>
    Python 字符串的几种拼装方式
    查看>>
    python 存入数据库bigint_python基础_MySQL的bigint类型
    查看>>
    python 学习 面向对象编程
    查看>>
    Python 学习日记第三篇 -- 字典
    查看>>
    Python 学习笔记(一)Data type
    查看>>
    python 安装echarts
    查看>>
    python 安装opencv及问题解决
    查看>>
    Python 安装程序:“写入文件 C:\Python27\pythonw.exe 时出错“
    查看>>
    Python 安装避坑指南:从入门到进阶
    查看>>
    Python 安装配置详解
    查看>>
    python 实现儿童算术游戏
    查看>>
    python 实现字符串转整型
    查看>>
    Python 实现定时任务的八种方案!
    查看>>
    Python 实现自动化测试 dubbo 协议接口
    查看>>
    python 对json数据读取及保存与读取,对dump,dumps,load,loads的理解
    查看>>
    Python 对mysql数据库的操作
    查看>>
    Python 对象数据库列表
    查看>>
    Python 导入requests报错No module named requests
    查看>>
    python 将函数加到列表中进行调用
    查看>>