动态规划(DP),压缩状态,插入字符构成回文字符串

题目链接:http://poj.org/problem?id=1159

解题报告:

1、LCS的状态转移方程为

if(str[i-1]==str[j-1])
  dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

2、由于开不了dp[5005][5005],于是考虑到压缩状态

这里采用滚动数组方式,LCS的状态转移方程可以改写为

if(str1[i-1]==str2[j-1])
{
    dp[i%2][j]=dp[(i-1)%2][j-1]+1;
}
else dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
  • Source Code
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#define MAX 5005

using namespace std;
///LCS的状态转移方程,d[i][j]=max(d[i-1][j],d[i][j-1]);
///LCS的滚动数组形式的状态转移方程,d[i%2][j]=max(d[(i-1)%2][j],d[i%2][j-1])
int dp[2][MAX];///滚动数组

int main()
{
    char str1[MAX],str2[MAX];
    int n;
    cin>>n;
    cin>>str1;
    for(int i=0; i<n; i++)
        str2[n-i-1]=str1[i];
    memset(dp,0,sizeof(dp));
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(str1[i-1]==str2[j-1])
            {
                dp[i%2][j]=dp[(i-1)%2][j-1]+1;
            }
            else dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
        }
    }
    printf("%d\n",n-dp[n%2][n]);
    return 0;
}

  

  

时间: 2024-10-14 09:01:05

动态规划(DP),压缩状态,插入字符构成回文字符串的相关文章

【动态规划】回文字符串

[动态规划]回文字符串 时间限制: 1 Sec  内存限制: 128 MB 题目描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串.现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串. 输入 第一行给出整数N(0<N<100) 接下来的N行,每行一个字符串,每个字符串长度不超过1000. 输出 每行输出所需添加的最少字符数

nyist oj 37 回文字符串 (动态规划经典)

回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串.现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串. 输入 第一行给出整数N(0<N<100) 接下来的N行,每行一个字符串,每个字符串长度不超过1000. 输出 每行输出所需添加的最少字符

HihoCOder1323 : 回文字符串(区间DP)

回文字符串 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个字符串 S ,最少需要几次增删改操作可以把 S 变成一个回文字符串? 一次操作可以在任意位置插入一个字符,或者删除任意一个字符,或者把任意一个字符修改成任意其他字符. 输入 字符串 S.S 的长度不超过100, 只包含'A'-'Z'. 输出 最少的修改次数. 样例输入 ABAD 样例输出 1 区间DP水题,见铺垫:密码脱落. #include<cstdio> #include<cstdlib

hihocoder 1323 - 回文字符串 - [hiho一下162周][区间dp]

用dp[i][j]表示把[i,j]的字符串str改写成回文串需要的最小操作步数. 并且假设所有dp[ii][jj] (ii>i , jj<j)都为已知,即包括dp[i+1][j].dp[i][j-1].dp[i+1][j-1]这三者都已知,则: 1. 如果str[i]==str[j],那么dp[i][j]=dp[i+1][j-1]: 2. 否则dp[i][j]可以分为: ①"一个字符"+"一个回文串"型:那么我们可以在str[i,j]后面加上一个字符,或

hihocoder 1323 回文字符串(字符串+dp)

题解: 比较水的题目 dp[i][j]表示[i...j]最少改变几次变成回文字符串 那么有三种转移 dp[i][j] = dp[i+1][j-1] + s[i] != s[j] dp[i][j] = dp[i+1][j] + 1(删除左边的字符,或者在右边添加一个字符与左边匹配) dp[i][j] = dp[i][j-1] + 1(删除右边的字符,或者在左边添加一个字符与右边匹配) #include <iostream> #include <cstring> #include &l

hiho 编程之美2015资格赛(回文字符序列-回文子序列数)

题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个.内容相同位置不同的子序列算不同的子序列. 输入 第一行一个整数T,表示数据组数.之后是T组数据,每组数据为一行字符串. 输出 对于每组数据

51Nod - 1092 回文字符串(添加删除字符LCS变形)

回文字符串 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串.每个字符串都可以通过向中间添加一些字符,使之变为回文字符串. 例如:abbc 添加2个字符可以变为 acbbca,也可以添加3个变为 abbcbba.方案1只需要添加2个字符,是所有方案中添加字符数量最少的. Input输入一个字符串Str,Str的长度 <= 1000.Output输出最少添加多少个字符可以使之变为回文字串.Sample Input abbc Sample Output 2 向字符串中间添加(

Light OJ 1258 Making Huge Palindromes 末尾添加最少字符变回文串

题目来源:Light OJ 1258 Making Huge Palindromes 题意:末尾添加最少的字符是使输入的串变成回文 输出长度 思路:直接KMP匹配出它和它反串的最大匹配 n减去它就是要添加的数量 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000010; char a[maxn], p[maxn]; int

5.13 添加最少字符使字符串整体都是回文字符串

[题目]: 给定一个字符串str,如果可以在str的任意位置添加字符,请返回在添加字符最少的情况下,让str整体都是回文字符串的一种结果 举例: str="ABA",str本身就是回文串,不需要添加字符,所以返回"ABA" str="AB",可以在'A'之前添加'B',使str整体都是回文串,故可以返回"BAB",也可以在'B'之后添加'A',使str整体都是回文串,故也可以返回"ABA",总之,只要添加的