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

[蓝桥杯]密码脱落

密码脱落

题目描述

X 星球的考古学家发现了一批古代留下来的密码。

这些密码是由 A、B、C、D 四种植物的种子串成的序列。

仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。

由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。

你的任务是:给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。

输入描述

输入一行,表示现在看到的密码串(长度不大于 1000)。

输出描述

要求输出一个正整数,表示至少脱落了多少个种子。

输入输出样例

示例 1

输入

ABCBA```txt
>输出
```txt
0
```txt#### 示例2>输入
```txt
ABDCDCBABC

输出

3

运行限制

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

总通过次数: 1860  |  总提交次数: 2184  |  通过率: 85.2%

难度: 困难   标签: 2016, 省赛, 动态规划

算法思路:动态规划求解最长回文子序列

​问题本质​​:计算使字符串变为回文串的最少删除字符数(即原字符串长度减去最长回文子序列长度)。
​核心思想​​:使用区间动态规划求解最长回文子序列(LPS),公式为:
最少删除数 = 字符串长度 - LPS长度

动态规划状态定义
  • dp[i][j]:表示子串 s[i..j] 的最长回文子序列长度
  • ​状态转移方程​​:
算法步骤
  1. ​初始化​​:

    • 单个字符的LPS长度为1:dp[i][i] = 1
    • 相邻字符若相同则LPS为2:s[i]==s[i+1] ? dp[i][i+1]=2 : 1
  2. ​区间扩展​​(长度3到n):

    • 枚举区间长度 len 从 3 到 n
    • 枚举左端点 i,计算右端点 j = i+len-1
    • 根据 s[i] 和 s[j] 是否相等更新 dp[i][j]
  3. ​结果计算​​:
    最少删除数 = n - dp[0][n-1]

算法演示

代码实现(C++)

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 1010;
int dp[N][N];int main() {string s;cin >> s;int n = s.size();// 初始化长度为1和2的区间for (int i = 0; i < n; i++) {dp[i][i] = 1;if (i < n-1) dp[i][i+1] = (s[i] == s[i+1]) ? 2 : 1;}// 区间DP:长度从3到nfor (int len = 3; len <= n; len++) {for (int i = 0; i + len - 1 < n; i++) {int j = i + len - 1;if (s[i] == s[j]) dp[i][j] = dp[i+1][j-1] + 2;else dp[i][j] = max(dp[i+1][j], dp[i][j-1]);}}cout << n - dp[0][n-1] << endl;return 0;
}

代码解析

  1. ​初始化阶段​​(L12-L17):

    • 对角线 dp[i][i]=1(单字符必为回文)
    • 相邻字符若相等则LPS=2,否则为1
  2. ​核心DP循环​​(L20-L27):

    • 外层循环:区间长度 len 从3到 n
    • 内层循环:左端点 i 遍历所有起始位置
    • 根据端点字符是否相等选择转移路径
  3. ​结果输出​​(L29):
    直接计算 n - dp[0][n-1]

实例验证

​输入​​LPS​​长度​​删除数​​输出​
"ABCBA""ABCBA"55-5=00
"ABDCDCBABC""ABDCDBA"710-7=33
"A""A"11-1=00
"AB""A"或"B"12-1=11

注意事项

  1. ​边界处理​​:

    • 当 j = i+1 时需单独初始化
    • 空串情况(题目保证非空)
  2. ​空间优化​​:

    • 使用滚动数组可将空间复杂度从 O(n2) 降为 O(n)
    int dp[2][N];  // 奇偶行交替计算
  3. ​时间效率​​:

    • 时间复杂度 O(n2),n=1000 时约 106 次操作
    • 1秒内可完成最大规模数据

多方位测试点

​测试类型​​输入样例​​预期输出​​验证要点​
最小边界"A"0单字符处理
相邻字符"AA"/"AB"0/1双字符回文判断
全相同字符"AAAAA"0完整回文处理
无回文子序列"ABCDEF"5最坏情况性能
交叉回文"ABADEDBA"2复杂序列处理
最大长度(1000)全A字符串0时间/空间边界

优化建议

  1. ​空间优化​​(滚动数组):

    bool cur = 0;
    for (int len=2; len<=n; len++) {cur = !cur;for (int i=0; j=i+len-1 < n; i++) {if (s[i]==s[j]) dp[cur][j] = dp[!cur][j-1] + 2;else dp[cur][j] = max(dp[!cur][j], dp[cur][j-1]);}
    }
  2. ​分支优化​​:

    // 预处理字符匹配
    if (s[i]==s[j]) dp[i][j] = dp[i+1][j-1] + 2;
    else dp[i][j] = max(dp[i][j-1], dp[i+1][j]); 
  3. ​并行计算​​(OpenMP):

    #pragma omp parallel for
    for (int len=3; len<=n; len++) {// 内层循环独立
    }
http://www.xdnf.cn/news/866737.html

相关文章:

  • NTC热敏电阻
  • 【Linux】进程
  • Pytorch模型格式区别( .pt .pth .bin .onnx)
  • nssm配置springboot项目环境,注册为windows服务
  • 【免杀】C2免杀技术(十五)shellcode混淆uuid/ipv6/mac
  • Mac 双系统
  • 深入详解开源工具DCMTK:C++开发的DICOM工具包
  • <el-table>构建树形结构
  • KrillinAI:视频跨语言传播的一站式AI解决方案
  • EasyRTC嵌入式音视频通信SDK音视频功能驱动视频业务多场景应用
  • HOPE800系列变频器安装到快速调试的详细操作说明
  • Delft3D软件介绍及建模原理和步骤;Delft3D数值模拟溶质运移模型建立;地表水环境影响评价报告编写思路
  • CppCon 2015 学习:3D Face Tracking and Reconstruction using Modern C++
  • 前端大数高精度计算解决方案,BigNumber.js
  • 前端面试二之运算符与表达式
  • 组件库二次封装——透传问题
  • UniApp 全生命周期钩子详解
  • 数据标注与大模型的双向赋能:效率与性能的跃升
  • CMake + Ninja 构建程序示例
  • CortexON:开源的多代理AI系统无缝自动化和简化日常任务
  • 【推荐算法】推荐系统核心算法深度解析:协同过滤 Collaborative Filtering
  • 07 APP 自动化- appium+pytest+allure框架封装
  • RabbitMQ 的异步化、解耦和流量削峰三大核心机制
  • ④Pybullet之Informed RRT*算法介绍及示例
  • 在本地查看服务器上的TensorBoard
  • Git安装与常用命令全攻略
  • Elasticsearch的搜索流程描述
  • 分类与逻辑回归 - 一个完整的guide
  • Git常用命令完全指南:从入门到精通
  • 正则表达式检测文件类型是否为视频或图片