当前位置: 首页 > news >正文

2025-10-19 hetao1733837刷题记录

LG2516 [HAOI2010] 最长公共子序列

原题链接:P2516 [HAOI2010] 最长公共子序列 - 洛谷

分析:是常见的LCS的dp求解问题。我们设dp1[i][j]表示A[1~i]与B[1~j]的LCS长度。

考虑转移,dp1[i][j] = \left\{\begin{matrix} dp1[i - 1][j - 1] + 1, A[i] == B[j]\\ max(dp1[i - 1][j], dp1[i][j - 1]),otherwise \end{matrix}\right.

OK,但是,这题还额外让我们统计LCS的个数,怎么办?

我们设dp2[i][j]表示A[1~i]与B[1~j]不同LCS的个数。

考虑转移,dp2[i][j]+=\left\{\begin{matrix} dp2[i - 1][j - 1], A[i] == B[j]\\ dp2[i - 1][j], f[i][j] == f[i - 1][j]\\ dp2[i][j - 1], f[i][j] == f[i][j - 1]\\ -dp2[i - 1][j - 1], A[i] != B[j]&and&f[i][j] == f[i - 1][j - 1] \end{matrix}\right.

初始化,dp2[0][j] = 1\\\\dp2[i][0] = 1

代码:

#include <bits/stdc++.h>
#define mod 100000000
using namespace std;
const int N = 5005;
int dp1[N][N], dp2[N][N]; //dp1统计LCS长度,dp2统计LCS个数
char a[N], b[N];//不敢用变量名y
string s;
int main(){int n = 0, k = 0;cin >> s;for (int i = 0; i < s.size() - 1; i++)a[++n] = s[i];cin >> s;for (int i = 0; i < s.size() - 1; i++)b[++k] = s[i];for (int i = 1; i <= n; i++){for (int j = 1; j <= k; j++){if (a[i] == b[j])dp1[i][j] = dp1[i - 1][j - 1] + 1;elsedp1[i][j] = max(dp1[i - 1][j], dp1[i][j - 1]);}}for (int i = 0; i <= n; i++)dp2[i][0] = 1;for (int j = 0; j <= k; j++)dp2[0][j] = 1;for (int i = 1; i <= n; i++){for (int j = 1; j <= k; j++){if (a[i] == b[j])dp2[i][j] = 1ll * (dp2[i][j] + dp2[i - 1][j - 1]) % mod;if (dp1[i][j] == dp1[i - 1][j])dp2[i][j] = 1ll * (dp2[i][j] + dp2[i - 1][j]) % mod;if (dp1[i][j] == dp1[i][j - 1])dp2[i][j] = 1ll * (dp2[i][j] + dp2[i][j - 1]) % mod;if (dp1[i][j] == dp1[i - 1][j - 1] && a[i] != b[j])dp2[i][j] = 1ll * (dp2[i][j] - dp2[i - 1][j - 1] + mod) % mod;}}cout << dp1[n][k] << '\n';cout << dp2[n][k];
}

咦,发现MLE了,嘻嘻,开两个5005*5005的二维数组当然会MLE,怎么办呢?

发现转移只会从上一个转下来,滚动数组滚一下就行了。

正解:

#include <bits/stdc++.h>
#define mod 100000000
using namespace std;
const int N = 5005;
int dp1_now[N], dp1_lst[N], dp2_now[N], dp2_lst[N];
char a[N], b[N];
string s;
int main(){int n = 0, k = 0;cin >> s;for (int i = 0; i < s.size() - 1; i++)a[++n] = s[i];cin >> s;for (int i = 0; i < s.size() - 1; i++)b[++k] = s[i];for (int j = 0; j <= k; j++){dp2_lst[j] = 1;}for (int i = 1; i <= n; i++){dp2_now[0] = 1;for (int j = 1; j <= k; j++){if (a[i] == b[j]){dp1_now[j] = dp1_lst[j - 1] + 1;} else{dp1_now[j] = max(dp1_lst[j], dp1_now[j - 1]);}dp2_now[j] = 0;if (a[i] == b[j]){dp2_now[j] = (dp2_now[j] + dp2_lst[j - 1]) % mod;}if (dp1_now[j] == dp1_lst[j]){dp2_now[j] = (dp2_now[j] + dp2_lst[j]) % mod;}if (dp1_now[j] == dp1_now[j - 1]){dp2_now[j] = (dp2_now[j] + dp2_now[j - 1]) % mod;}if (a[i] != b[j] && dp1_now[j] == dp1_lst[j - 1]){dp2_now[j] = (dp2_now[j] - dp2_lst[j - 1] + mod) % mod;}}swap(dp1_now, dp1_lst);swap(dp2_now, dp2_lst);}cout << dp1_lst[k] << '\n';cout << dp2_lst[k];return 0;
}

这里我们重新设了dp方程,详细如下:

dp1_lst[j] = dp1[i - 1][j]

dp1_now[j] = dp1[i][j]

dp2_lst[j]=dp2[i-1][j]

dp2_now[j]=dp2[i][j]

转移与原来保持一致。

http://www.dtcms.com/a/503293.html

相关文章:

  • 批量字符替换工具,支持多种格式
  • 50.情感分析:AI读懂你的心情
  • 嵌入式Linux开发环境学习(二)
  • 分析静态代码分析工具
  • unix做网站常用的数据库用php做网站后台
  • Fiddler抓包+Postman实战之--客户关系管理软件自动化测试
  • 『 数据库 』MySQL复习 - 从更新删除到分组聚合查询实践
  • 力扣2025.10.19每日一题
  • 广州站扩建百度系app
  • 品牌微信网站开发企业网站排版规则
  • Java Socket 多线程实例
  • 机器学习01——概述
  • es的docker部署和docker相关的可可视化面板工具介绍
  • Java 反射机制深度剖析:性能与安全性的那些坑
  • SQLDeveloper 调试存储过程ORA-24247
  • 网站虚拟主机过期云霄县建设局网站
  • 如何通过共享内存和寄存器溢出优化CUDA内核性能
  • ArcMap转化图片为TIF
  • Kubernetes(K8s) —— 部署(保姆级教程)
  • 用 Python 写一个自动化办公小助手
  • 《二叉树“防塌”指南:AVL 树如何用旋转 “稳住” 平衡?》
  • 网站制作wap页面wordpress微信公众平台开发
  • 分解如何利用c++修复小程序的BUG
  • 若依微服务 nacos的配置文件
  • 63.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--预算告警
  • 网站建设没有业务怎么办德州网架公司
  • 九成自动化备份知乎专栏
  • 圆形平面阵列与平面方形阵的导向矢量:原理与实现
  • Altium Designer(AD24)Help帮助功能总结
  • 网站建设 个人2012版本wordpress