• 2016级算法期末上机-G.中等·Bamboo's Fight with DDLs II


    中等·Bamboo's Fight with DDLs II

    分析

    一句话:给定字符串,求最长回文子序列长度,动态规划LCS思想的进阶应用

    具体思路如下:
    对于任意字符串,如果头尾字符相同,那么字符串的最长回文子序列等于去掉首尾的字符串的最长子序列加上首尾;如果首尾字符不同,则最长回文子序列等于去掉头的字符串的最长回文子序列和去掉尾的字符串的最长回文子序列的较大者。

    因此动态规划的状态转移方程为:

    设字符串为str,长度为n,dp[i][j]表示第i到第j个字符间的回文子序列的最大长度(i<=j),则:

    状态初始条件:dp[i][i]=1 (i=0:n-1)

    状态转移方程:

      dp[i][j]=dp[i+1][j-1] + 2  if(str[i]==str[j])
    
      dp[i][j]=max(dp[i+1][j],dp[i][j-1])  if (str[i]!=str[j])
    

    你可能已经发现,这和LCS的状态转移几乎没什么两样,没错,最长回文子序列LPS其实就是最长公共子序列LCS,为什么呢?你想一下,如果把字符串反转,看作第二个字符串,那我要求的,不就是这两个字符串的LCS吗?对不对,对不对!

    代码样例

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxx = 505;
    int dp[maxx][maxx];
    string str;
    int main()
    {
    	while(cin>>str)
        {
            for(int i = 0;i<maxx;i++)
                dp[i][i]=1;
            int len = str.length();
            for(int i = len-1;i>=0;i--)
                for(int j = i+1;j<len;j++)
            {
                if(str[i]==str[j])
                    dp[i][j]=dp[i+1][j-1]+2;
                else
                    dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
    
            }
            printf("%d
    ",dp[0][len-1]);
        }
    }
    
  • 相关阅读:
    使用DirectX作渲染过程
    记于来北京两个星期
    添加 node mocha 测试模块
    for-of循环
    app-web 开发 追溯debug
    cmd关闭被占用的端口命令及教程详解
    vue使用element-ui的el-input监听不了键盘事件解决
    Nodejs 进阶:Express 常用中间件 body-parser 实现解析
    nodejs设置允许跨域
    nodejs 全局变量和全局对象
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8215897.html
Copyright © 2020-2023  润新知