【C++刷题】优选算法——动态规划第四辑

server/2024/10/18 18:27:41/
  1. 回文子串
状态表示:dp[i][j]: 表示以i位置开始,j位置结尾的子串是否是回文串
状态转移方程:i == j: dp[i][j] = true;i + 1 == j && s[i] == s[j]: dp[i][j] = true;i + 1 < j && dp[i+1][j-1] && s[i] == s[j]: dp[i][j] = true;
int countSubstrings(string s)
{// 1.dp数组vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));// 2.初始化// 3.状态转移方程for(int i = s.size() - 1; i >= 0; --i){for(int j = i; j < s.size(); ++j){if(i == j){dp[i][j] = true;}else if(i + 1 == j){if(s[i] == s[j]) dp[i][j] = true;}else{if(dp[i+1][j-1] && s[i] == s[j]) dp[i][j] = true;}}}// 4.返回值int ret = 0;for(int i = s.size() - 1; i >= 0; --i){for(int j = i; j < s.size(); ++j){ret += dp[i][j];}}return ret;
}
  1. 最长回文子串
状态表示:dp[i][j]: 表示以i位置开始,j位置结尾的子串是否是回文串
状态转移方程:i == j: dp[i][j] = true;i + 1 == j && s[i] == s[j]: dp[i][j] = true;i + 1 < j && dp[i+1][j-1] && s[i] == s[j]: dp[i][j] = true;
string longestPalindrome(string s) 
{// 1.dp数组vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));// 2.初始化// 3.状态转移方程for(int i = s.size() - 1; i >= 0; --i){for(int j = i; j < s.size(); ++j){if(i == j){dp[i][j] = true;}else if(i + 1 == j){if(s[i] == s[j]) dp[i][j] = true;}else{if(dp[i+1][j-1] && s[i] == s[j]) dp[i][j] = true;}}}// 4.返回值int start = -1, end = -1;for(int i = s.size() - 1; i >= 0; --i){for(int j = i; j < s.size(); ++j){if(dp[i][j] == true){if(start == -1){start = i;end = j;}else{if(j - i > end - start){start = i;end = j;}}}}}return s.substr(start, end - start + 1);
}
  1. 分割回文串 IV
状态表示:dp[i][j]: 表示以i位置开始,j位置结尾的子串是否是回文串
状态转移方程:i == j: dp[i][j] = true;i + 1 == j && s[i] == s[j]: dp[i][j] = true;i + 1 < j && dp[i+1][j-1] && s[i] == s[j]: dp[i][j] = true;
bool checkPartitioning(string s)
{// 1.dp数组vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));// 2.初始化// 3.状态转移方程for(int i = s.size() - 1; i >= 0; --i){for(int j = i; j < s.size(); ++j){if(i == j) dp[i][j] = true;else if(i + 1 == j && s[i] == s[j]) dp[i][j] = true;else if(dp[i+1][j-1] && s[i] == s[j]) dp[i][j] = true;}}// 4.返回值for(int i = 1; i < s.size() - 1; ++i){for(int j = i; j < s.size() - 1; ++j){if(dp[0][i-1] && dp[i][j] && dp[j+1][s.size() - 1]) return true;}}return false;
}
  1. 分割回文串 II
状态表示:dp[i]: 表示 s[0, i]这个子串区间,最少的分割次数
状态转移方程:dp[i] = min(dp[j-1]+1)
int minCut(string s)
{// 0.优化vector<vector<bool>> vv(s.size(), vector<bool>(s.size(), false));for(int i = s.size() - 1; i >= 0; --i){for(int j = i; j < s.size(); ++j){if(i == j) vv[i][j] = true;else if(i + 1 == j && s[i] == s[j]) vv[i][j] = true;else if(vv[i+1][j-1] && s[i] == s[j]) vv[i][j] = true;}}// 1.dp数组vector<int> dp(s.size());// 2.初始化// 3.状态转移方程for(int i = 0; i < dp.size(); ++i){if(vv[0][i]) dp[i] = 0;else{int m = INT_MAX;for(int j = i; j > 0; --j){if(vv[j][i]) m = min(m, dp[j-1] + 1);}dp[i] = m;}}// 4.返回值return dp.back();
}
  1. 最长回文子序列
状态表示:dp[i][j]: 表示s字符串[i,j]区间内的所有子序列中,最长回文子序列的长度
状态转移方程:s[i] == s[j]:if(i == j) dp[i][j] = 1;else if(i + 1 == j) dp[i][j] = 2;else dp[i][j] = dp[i+1][j-1] + 2;s[i] != s[j]:dp[i][j] = max(dp[i+1][j], dp[i][j-1]);
int longestPalindromeSubseq(string s)
{// 1.dp数组vector<vector<int>> dp(s.size(), vector<int>(s.size()));// 2.初始化// 3.状态转移方程for(int i = s.size() - 1; i >= 0; --i){for(int j = i; j < s.size(); ++j){if(s[i] == s[j]){if(i == j) dp[i][j] = 1;else if(i + 1 == j) dp[i][j] = 2;else dp[i][j] = dp[i+1][j-1] + 2;}else{dp[i][j] = max(dp[i+1][j], dp[i][j-1]);}}}// 4.返回值return dp[0][s.size() - 1];
}
  1. 让字符串成为回文串的最少插入次数
状态表示:dp[i][j]: 表示s字符串中[i,j]区间的子串,成为回文串的最小插入次数
状态转移方程:s[i] == s[j]:if(i == j || i + 1 == j) dp[i][j] = 0;else dp[i][j] = dp[i+1][j-1];s[i] != s[j]:dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1;
int minInsertions(string s)
{// 1.dp数组vector<vector<int>> dp(s.size(), vector<int>(s.size()));// 2.初始化// 3.状态转移方程for(int i = s.size(); i >= 0; --i){for(int j = i; j < s.size(); ++j){if(s[i] == s[j]){if(i == j || i + 1 == j) dp[i][j] = 0;else dp[i][j] = dp[i+1][j-1];}else{dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1;}}}// 4.状态转移方程return dp[0][s.size() - 1];
}

http://www.ppmy.cn/server/7471.html

相关文章

计算机网络实验——学习记录五(TCP协议2)

一、TCP协议重传机制 TCP协议是一种面向连接、可靠的传输层协议。为了保证数据的可靠传输&#xff0c;TCP采用数据包重传的机制来应对网络传输过程中可能出现的丢包、错包和乱序等问题。 TCP协议的重传包括超时重传、快速重传、带选择确认SACK的重传和重复SACK重传四种。 二、…

比特币减半后:见证历史性暴涨吗?

作者&#xff1a;Alex Thorn、Gabe Parker and Simrit Dhinsa Galaxy 编译&#xff1a;Liam 比特币减半概述 比特币发行的透明度和可预测性是该资产区别于世界上任何其他资产或货币的关键特征。其他任何资产都没有一个可计算的通货膨胀时间表&#xff0c;也没有一个已知的供应事…

Redis如何查看KEY的数据类型

1. 查看数据类型 在Redis中&#xff0c;可以使用 TYPE 命令来查看指定key的数据类型。该命令会返回存储在指定key中的值的数据类型。以下是具体的使用方法和步骤&#xff1a; 连接到Redis服务器&#xff1a;首先&#xff0c;你需要使用Redis客户端工具&#xff08;如命令行工具…

[已解决]react打包部署

react打包部署 问题 npm install 命令无反应 思路 换成 yarn install 安装完hadoop的环境后&#xff0c;使用node的yarn会报错&#xff1a; 我们在cmd使用where yarn&#xff0c;如下&#xff1a; 看你想保留哪一个&#xff0c;我平时node用的多&#xff0c;就把hadoop的y…

Spring-AOP

文章目录 1.基本介绍1.什么是AOP&#xff1f;2.示意图3.五种通知 2.AOP快速入门1.入门案例1.导入jar包2.Cal.java 接口3.CalImpl.java 实现类4.CalAspect.java 切面类5.beans06.xml 开启注解功能6.测试 2.细节说明3.AOP理解&#xff08;重点&#xff09;1.使用场景2.代理对象理…

【Redis 神秘大陆】001 背景基础理论

一、背景&基础理论 1.1 什么是缓存 缓存&#xff1a;存储在计算机上的一个原始数据复制集&#xff0c;以便于访问——维基百科 1.2 为什么用缓存 提升用户体验&#xff1a; 【即效率、效益和基本主观满意度】CAST 使用者的状态、系统性能及环境&#xff0c;不同的人对于…

JAVA反射-loadClass和Class.forName的区别

类初始化的时机: ▲何时会触发类初始化? 对于第一次JVM执行&#xff0c;类初始化只执行1次&#xff01; 类会执行初始化。 通常来说&#xff0c;只要你使用该类&#xff0c;都属于主动使用类。但以下几种情况不属于主动使用: 1.使用类声明&#xff08;定义&#xff09;变量 2…

Git学习笔记(二)Git安装及基础命令

前面的文章中&#xff0c;我们已经对Git的一些基础知识进行了简单的介绍&#xff0c;包括它的作用&#xff0c;Git组件&#xff0c;文件状态以及一些简单的命令介绍等等。那么这一章主要介绍如何下载安装配置Git&#xff0c;以及Git的一些常用命令和实操截图。 Git下载与安装 …