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

[蓝桥杯]最优包含

最优包含

题目描述

我们称一个字符串 SS 包含字符串 TT 是指 TT 是 SS 的一个子序列,即可以从字符串 SS 中抽出若干个字符,它们按原来的顺序组合成一个新的字符串与 TT 完全一样。

给定两个字符串 SS 和 TT,请问最少修改 SS 中的多少个字符,能使 SS 包含 TT ?

其中,1≤∣T∣≤∣S∣≤10001≤∣T∣≤∣S∣≤1000。

输入描述

输入两行,每行一个字符串。

第一行的字符串为 SS,第二行的字符串为 TT。

两个字符串均非空而且只包含大写英文字母。

输出描述

输出一个整数,表示答案。

输入输出样例

示例

输入

ABCDEABCD
XAABZ

输出

3

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

总通过次数: 1879  |  总提交次数: 2244  |  通过率: 83.7%

难度: 中等   标签: 2019, 国赛, 动态规划

方法思路

这个问题要求我们找到最少需要修改字符串S中的多少个字符,使得字符串T成为S的子序列。关键在于动态规划的应用,通过构建一个二维数组来记录状态转移,从而高效地解决问题。

动态规划思路:

  1. 状态定义: 定义dp[i][j]表示考虑S的前i个字符和T的前j个字符时,最少需要修改的字符数目,使得T的前j个字符是S的前i个字符的子序列。

  2. 初始化:

    • dp[0][0] = 0表示两个空字符串不需要任何修改。

    • 对于i > 0j = 0的情况,dp[i][0] = 0,因为T为空时不需要任何字符。

    • 对于j > 0i = 0的情况,dp[0][j] = INF(无穷大),因为S为空时无法包含非空的T。

  3. 状态转移:

    • 如果S[i-1] == T[j-1],则dp[i][j] = dp[i-1][j-1],即当前字符匹配,无需修改。

    • 否则,dp[i][j] = min(dp[i-1][j-1] + 1, dp[i-1][j]),即可以选择修改当前字符(增加修改次数)或者不匹配当前字符(保持之前的修改次数)。

  4. 结果提取: 最终的结果是dp[m][n],其中m和n分别是S和T的长度。我们需要在所有可能的起始位置中找到最小的修改次数,即遍历dp[i][n],其中inm

    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    using namespace std;int main() {string S, T;cin >> S >> T;int m = S.size();int n = T.size();// dp[i][j] 表示S的前i个字符包含T的前j个字符所需的最小修改次数vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));// 初始化:当T为空串时,不需要任何修改for (int i = 0; i <= m; ++i) {dp[i][0] = 0;}// 初始化:当S为空串且T非空时,无法包含,设为无穷大(这里用m+1代替,因为最大修改次数不会超过m)for (int j = 1; j <= n; ++j) {dp[0][j] = m + 1; // 表示不可达}for (int i = 1; i <= m; ++i) {for (int j = 1; j <= n; ++j) {if (S[i - 1] == T[j - 1]) {dp[i][j] = dp[i - 1][j - 1];} else {dp[i][j] = min(dp[i - 1][j - 1] + 1, dp[i - 1][j]);}}}// 在S的所有可能位置中寻找最小的修改次数int result = m + 1;for (int i = n; i <= m; ++i) {result = min(result, dp[i][n]);}cout << result << endl;return 0;
    }

    代码解释

  5. 输入处理: 读取两个字符串S和T。

  6. 初始化动态规划数组: dp[i][j]用于存储状态,初始时处理边界条件(空字符串的情况)。

  7. 状态转移: 遍历S和T的每个字符,根据字符是否匹配更新状态。若字符匹配,则直接继承之前的状态;否则,选择修改当前字符或跳过当前字符中的较小值。

  8. 结果提取: 在所有可能的结束位置中查找最小的修改次数,确保T是S的子序列。

  9. 输出结果: 打印最少需要修改的字符数目。

http://www.lryc.cn/news/2401399.html

相关文章:

  • NuxtJS入门指南:环境安装及报错解决
  • 在java 项目 springboot3.3 中 调用第三方接口(乙方),如何做到幂等操作(调用方为甲方,被调用方为乙方)? 以及啥是幂等操作?
  • 贪心算法应用:集合划分问题详解
  • electron下载文件
  • Neo4j 数据导入:原理、技术、技巧与最佳实践
  • 数论~~~
  • web第十次课后作业--Mybatis的增删改查
  • 贪心算法应用:集合覆盖问题详解
  • BLOB 是用来存“二进制大文件”的字段类型
  • 5.Declare_Query_Checking.ipynb
  • 【知识点】第7章:文件和数据格式化
  • NetSuite Bundle - Dashboard Refresh
  • AI+3D 视觉重塑塑料袋拆垛新范式:迁移科技解锁工业自动化新高度
  • 智慧赋能:移动充电桩的能源供给革命与便捷服务升级
  • 【项目实践】SMBMS(Javaweb版)(三)登出、注册、注销、修改
  • 斐波那契数列------矩阵幂法
  • 【Go语言基础【四】】局部变量、全局变量、形式参数
  • DeepSeek 赋能车路协同:智能交通的破局与重构
  • RabbitMQ 的异步化、解耦和流量削峰三大核心机制
  • Ubuntu 25.10 将默认使用 sudo-rs
  • Maven​​ 和 ​​Gradle​​ 依赖管理的详细说明及示例,涵盖核心概念、配置方法、常见问题解决和工具对比。
  • 【Web应用】若依框架:基础篇21二次开发-页面调整
  • 【 java 基础知识 第一篇 】
  • CVE-2020-17518源码分析与漏洞复现(Flink 路径遍历)
  • Excel表格批量下载 CyberWin Excel Doenlaoder 智能编程-——玄武芯辰
  • 可编辑PPT | 基于大数据中台新能源智能汽车应用解决方案汽车大数据分析与应用解决方案
  • 【统计方法】基础分类器: logistic, knn, svm, lda
  • AtomicInteger原子变量和例题
  • simulink有无现成模块可以实现将三个分开的输入合并为一个[1*3]的行向量输出?
  • k8s集群安装坑点汇总