zoukankan      html  css  js  c++  java
  • 最长回文子序列---DP

    问题描述

    给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000

    解题思路

    1.说明

    首先要弄清楚回文子串和回文子序列的区别,如果一个字符串是“bbbab”,那么它的回文子串为“bbb”,但是其回文子序列是“bbbb”,这是因为回文子序列中可以相隔字符,不一定要连续。

    2.思路

    定义dp数组的含义。这里我们定义一个二维数组dp

    dp[i][j]表示字符串str从i到j的字符串中最长回文子序列的长度。

    假设我们现在已经知道dp[i+1][j-1]的值,那么dp[i][j]的值只需要判断s[i]和s[j]是否相等即可。

    如果s[i]=s[j],那么dp[i][j]=dp[i+1][j-1]+2,直接加2即可。

    如果s[i]!=s[j],说明s[i]和s[j]至少是不在这个回文序列的,表明这时的dp[i][j]只需取两者之间的最大值即可,那么dp[i][j]=Max(dp[i][j-1],dp[i+1][j])。

    3. 举例说明

    例如字符串“bbbab”,在创建数组之前,可以先将如下矩阵的部分内容填好,因为dp[i][i]一个字符即可构成一个回文序列,所以有dp[i][i]=1。同时,dp[i][j](i>j)=0;即不存在。

    然后可以从下往上来计算。

    ij 0 1 2 3 4
    0 1  2  2  4
    1 0 1  2  3
    2 0 0 1  3
    3 0 0 0 1  1
    4 0 0 0 0 1

    填满表格最后的一个数即为回文子序列最长的长度。返回dp[o][4]即可。

    3. 代码

    int longestPalindromeSubseq(char * s){
        int N=strlen(s);
        int dp[N][N]; //dp[i][j]表示从i到j回文子序列的长度
        for(int i=0;i<N;++i){
            for(int j=0;j<N;++j){
                if(i==j) dp[i][j]=1;
                else dp[i][j]=0;
            }
        }
        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]=fmax(dp[i][j-1],dp[i+1][j]);
            }
        }
        return dp[0][N-1];
    
    }
  • 相关阅读:
    Mybatis(三)
    Mybatis(二)
    Mybatis
    AJAX的跨域
    AJAX
    EL表达式与标准标签库JSTL
    java无脚本jsp页面-简介
    javaWeb的开发模式
    ADO.Net之SqlConnection、sqlcommand的应用
    翻译1-在SQL Server 2016中介绍微软R服务
  • 原文地址:https://www.cnblogs.com/laysfq/p/12930942.html
Copyright © 2011-2022 走看看