【编程题-错题集】最长回文子序列(动态规划 - 区间dp)

简介: 【编程题-错题集】最长回文子序列(动态规划 - 区间dp)

牛客对应题目链接:最长回文子序列_牛客题霸_牛客网 (nowcoder.com)


一、分析题目

基础的区间 dp 问题:

1、状态表示

dp[i][j] 表示:字符串 [i, j] 区间内的最长回文子序列的长度。


2、状态转移方程

  1. 当 i > j,dp[i][j] = 0(不讨论这种情况,可以保证不存在这种情况)
  2. 当 i == j 的时候,只有⼀个字符,长度为 1,即 dp[i][j] = 1;
  3. 当 i < j 的时候,分情况讨论:
  • s[i] == s[j]: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]);

3、初始化

根据状态转移方程,可以知道 dp[i][j] 的取值方向只会从它的左边、左下、下面三个方向去取,而这些方向除了 i==j 时是初始化为 1 的以外,其它的都是 i > j,不需要另外进行初始化。


4、填表顺序

从下往上,从左往右。


5、返回值

dp[0][n-1](可以返回状态表示的含义去思考返回值)


二、代码

1、力扣AC代码

//动态规划-二维dp
class Solution {
public:
    int longestPalindromeSubseq(string s) {
        int n=s.size();
        vector<vector<int>> dp(n, vector<int>(n));
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                if(i==j) dp[i][j]=1;
        for(int i=n-1; i>=0; i--)
        {
            for(int j=i+1; j<n; j++)
            {
                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]);
            }
        }
        return dp[0][n-1];
    }
};
 
//动态规划-二维dp-优化
class Solution {
public:
    int longestPalindromeSubseq(string s) {
        int n=s.size();
        vector<vector<int>> dp(n, vector<int>(n));
        for(int i=0; i<n; i++)
            dp[i][i]=1;
        for(int i=n-1; i>=0; i--)
        {
            for(int j=i+1; j<n; j++)
            {
                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]);
            }
        }
        return dp[0][n-1];
    }
};

2、值得学习的代码

#include <iostream>
#include <string>
 
using namespace std;
 
int dp[1010][1010];
 
int main()
{
    string s;
    cin >> s;
    int n = s.size();
 
    for(int i = n - 1; i >= 0; i--)
    {
        dp[i][i] = 1;
        for(int j = i + 1; j < n; j++)
        {
            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 << dp[0][n - 1] << endl;
 
 return 0;
}

三、反思与改进

做这道题时,我还是想到了之前写过的5. 最长回文子串 - 力扣(LeetCode),然后就还是按着之前的分类讨论的思路去写了,结果只能通过一般的测试样例。忽略了这两道题目的不同之处:之前写的题目要求的是子串,说明是连续序列;而这道题目要求的是子序列,并没有要求是连续的,所以这两道题目的解法肯定不一样。

本题应该是与516. 最长回文子序列 - 力扣(LeetCode)要求一致,不过这道题之前也写过,印象不深刻,说明没有掌握这类题目的本质,不熟练就多做几次吧。


相关文章
|
11月前
|
人工智能 JSON 机器人
10分钟!用飞书卡片+n8n零代码搞定自动化
手把手教你用飞书卡片+n8n搭建零代码自动化应用。
|
敏捷开发 人工智能 数据可视化
2025年必备的任务跟踪管理工具深度解析:10款提升团队协作效率的专业平台
任务跟踪管理工具在企业运营中日益重要,尤其在2025年,AI驱动、实时协作、跨平台同步及系统集成成为主要趋势。本文介绍了10款必备工具,如PingCode、Worktile、Trello、Jira等,并分析了其适用场景与功能特点,帮助企业根据团队规模、工作方法论和集成需求选择合适工具,提升协作效率与项目管理水平。
591 3
|
机器学习/深度学习 编解码 自然语言处理
【文献学习】An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale
本文介绍了如何使用纯Transformer模型进行图像识别,并讨论了模型的结构、训练策略及其在多个图像识别基准上的性能。
1243 3
|
存储 运维 监控
批量开启 SLS 服务日志
背景 SLS 服务日志支持记录 Project 内的用户操作日志等多种日志数据,并提供多种分析维度的仪表盘。在开通此功能后,相关的日志都会被存储到指定位置(project)下的两个特殊 logstore:internal-operation_log 以及 internal-diagnostic_log,我们可以像操作普通 logstore 一样,对它们进行查询、分析、消费以及构建仪表盘等。
2089 0
|
网络协议 Windows
glusterfs 客户端访问
访问glusterfs- 配置GlusterFS 客户端 访问glusterfs卷有多种方式. 1.使用Gluster Native Client 模式:这种方式提供了高并发,高性能,传输失败恢复机制,但只适用于GNU/Linux.
2539 0
|
15天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
8158 15
|
14天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
2332 13
|
13天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1846 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!

热门文章

最新文章