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

    你可能感兴趣的文章
    Prometheus快速搭建与监控Linux系统实战
    查看>>
    prometheus报警与恢复告警的格式
    查看>>
    Pytorch中安装 torch_geometric 详细图文操作(全)
    查看>>
    prometheus监控docker容器实战
    查看>>
    Prometheus监控k8s集群使用邮箱和微信告警!
    查看>>
    Prometheus监控mysq数据库实战
    查看>>
    prometheus监控nginx实战
    查看>>
    Prometheus监控redis数据库实战
    查看>>
    Prometheus监控教程:使用Grafana展示主机基本信息
    查看>>
    pytorch中如何使用预训练词向量
    查看>>
    Prometheus监控教程:使用PromQL查询监控数据(上篇)
    查看>>
    Prometheus监控教程:使用PromQL查询监控数据(下篇)
    查看>>
    Pytorch中关于forward函数的理解与用法
    查看>>
    Prometheus监控教程:安装部署
    查看>>
    Prometheus监控教程:配置介绍
    查看>>
    Pytorch中tqdm进度条的使用
    查看>>
    Prometheus(2):SpringBoot 2.X集成Prometheus
    查看>>
    Promise 原理解析与实现(遵循Promise/A+规范)
    查看>>
    PyTorch:传递 numpy 数组进行权重初始化
    查看>>
    PyTorch-Tutorials【pytorch官方教程中英文详解】- 8 Save and Load Model
    查看>>