d.求对字符串最少添加几个字符可变为回文串。

s.

法1:直接对它和它的逆序串求最长公共子序列长度len。N-len即为所求。(N为串长度)

因为,要求最少添加几个字符,我们可以先从原串中找到一个最长回文子序列,然后对于原串中不属于这个回文子序列的字符,在串中的相应位置添加一个相同的字符即可。那么需要添加的字符数量即为N-len。

最长回文串可以看作是原串中前面和后面字符的一种匹配(每个后面的字符在前面找到一个符合位置要求的与它相同的字符)。这种的回文匹配和原串与逆序串的公共子序列是一一对应的(一个回文匹配对应一个公共子序列,反之亦然),而且两者所涉及到的原串中的字符数量是相等的,也就是最长公共子序列对应最长回文串。原因陈述完毕。

dp[i][j]表示原串前i个字符与逆序串前j个字符的最长公共子序列

if(str[i-1]==str2[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[i][j]表示从i到j这段子串若变为回文串最少添加的字符数。

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

c.法1

/*
用short险过 dp[i][j]表示原串前i个字符与逆序串前j个字符的最长公共子序列 if(str[i-1]==str2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}
else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
} */
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; #define MAXN 5005 short dp[MAXN][MAXN];
char str[MAXN],str2[MAXN]; int main(){ int N;
int i,j; while(~scanf("%d",&N)){ scanf("%s",str); for(i=,j=N-;i<N;++i,--j){
str2[i]=str[j];
} memset(dp,,sizeof(dp));
for(i=;i<=N;++i){
for(j=;j<=N;++j){
if(str[i-]==str2[j-]){
dp[i][j]=dp[i-][j-]+;
}
else{
dp[i][j]=max(dp[i-][j],dp[i][j-]);
}
}
} printf("%d\n",N-dp[N][N]);
} return ;
}

ps:其实可以用滚动数组

c'.滚动数组

/*
用short险过 dp[i][j]表示原串前i个字符与逆序串前j个字符的最长公共子序列 if(str[i-1]==str2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}
else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
} */
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; #define MAXN 5005 short dp[][MAXN];//滚动数组
char str[MAXN],str2[MAXN]; int main(){ int N;
int i,j; while(~scanf("%d",&N)){ scanf("%s",str); for(i=,j=N-;i<N;++i,--j){
str2[i]=str[j];
} memset(dp,,sizeof(dp));
for(i=;i<=N;++i){
for(j=;j<=N;++j){
if(str[i-]==str2[j-]){
dp[i%][j]=dp[(i-)%][j-]+;
}
else{
dp[i%][j]=max(dp[(i-)%][j],dp[i%][j-]);
}
}
} printf("%d\n",N-dp[N%][N]);
} return ;
}

c2.法2

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; #define MAXN 5005 short dp[MAXN][MAXN];
char str[MAXN]; int main(){ int N;
int i,j; while(~scanf("%d",&N)){
scanf("%s",str); memset(dp,,sizeof(dp)); for(i=N-;i>=;--i){
dp[i][i]=;
for(j=i+;j<N;++j){
if(str[i]==str[j]){
dp[i][j]=dp[i+][j-];
}
else{
dp[i][j]=min(dp[i+][j],dp[i][j-])+;
}
}
} printf("%d\n",dp[][N-]);
} return ;
}

c2'.滚动数组

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; #define MAXN 5005 short dp[][MAXN];//滚动数组
char str[MAXN]; int main(){ int N;
int i,j; while(~scanf("%d",&N)){
scanf("%s",str); memset(dp,,sizeof(dp)); for(i=N-;i>=;--i){
dp[i%][i%]=;
for(j=i+;j<N;++j){
if(str[i]==str[j]){
dp[i%][j]=dp[(i+)%][j-];
}
else{
dp[i%][j]=min(dp[(i+)%][j],dp[i%][j-])+;
}
}
} printf("%d\n",dp[][N-]);
} return ;
}

POJ - 1159 Palindrome(dp-回文变形)的更多相关文章

  1. POJ 3280 Cheapest Palindrome(DP 回文变形)

    题目链接:http://poj.org/problem?id=3280 题目大意:给定一个字符串,可以删除增加,每个操作都有代价,求出将字符串转换成回文串的最小代价 Sample Input 3 4 ...

  2. poj 3280 Cheapest Palindrome ---(DP 回文串)

    题目链接:http://poj.org/problem?id=3280 思路: dp[i][j] :=第i个字符到第j个字符之间形成回文串的最小费用. dp[i][j]=min(dp[i+1][j]+ ...

  3. HDU 1513 && POJ 1159 Palindrome (DP+LCS+滚动数组)

    题意:给定一个字符串,让你把它变成回文串,求添加最少的字符数. 析:动态规划是很明显的,就是没有了现思路,还是问的别人才知道,哦,原来要么写,既然是回文串, 那么最后正反都得是一样的,所以我们就正反求 ...

  4. poj 1159 Palindrome(dp)

    题目:http://poj.org/problem?id=1159 #include<iostream> #include<cstring> #include<cstdi ...

  5. poj 1159 最长回文

    方法  LCS #include<iostream> #include<cstring> #include<algorithm> #include<stdio ...

  6. POJ 1159 Palindrome(字符串变回文:LCS)

    POJ 1159 Palindrome(字符串变回文:LCS) id=1159">http://poj.org/problem? id=1159 题意: 给你一个字符串, 问你做少须要 ...

  7. CF932G Palindrome Partition(回文自动机)

    CF932G Palindrome Partition(回文自动机) Luogu 题解时间 首先将字符串 $ s[1...n] $ 变成 $ s[1]s[n]s[2]s[n-1]... $ 就变成了求 ...

  8. [LeetCode] Valid Palindrome 验证回文字符串

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  9. dp回文

    .dp回文子串 通常在dp数组中存放的是 从i到j是否是回文子串 1.动态规划 2.中心扩展法 #include<iostream> #include<algorithm> # ...

随机推荐

  1. Linux-LNMP LAMP LNMPA

    这个脚本是使用shell编写,为了快速在生产环境上部署lnmp/lamp/lnmpa(Linux.Nginx/Tengine.MySQL/MariaDB/Percona.PHP),适用于CentOS ...

  2. iOS 下拉刷新和加载更多 (OC\Swift)

    Swift语言出来之后, 可能还没有第三方的下拉刷新和上提加载, 所以自己用UIRefreshControl控件和UITableView实例的tableFooterView(底部视图)属性结合起来写了 ...

  3. java远程调试(断点)程序/tomcat( eclipse远程调试Tomcat方法)

    tomcat远程调试: 1.Linux中配置tomcat在catalina.sh中添加如下CATALINA_OPTS="-Xdebug  -Xrunjdwp:transport=dt_soc ...

  4. mysqlbinlog快速遍历搜索记录 (转)

    目标,开发人员说有个数据莫名其妙添加了,但是不知道是从哪里添加的,而且应用功能里面不应该添加这样的数据,为了查清楚来源,所 以我就准备去binlog里面找了,但是binlog有好几个月的数,我这样一个 ...

  5. Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解

    Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解 (本文转自: http://blog.csdn.net/yinhaide/article/details/44756 ...

  6. 【linux】linux启动过程

  7. Javascript中函数的四种调用方式

    一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...

  8. Python基础教程【读书笔记】 - 2016/7/7

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第四波:第5章  条件.循环和其他语句 [总览]  深入介绍条件语句和循环语句,随后会看到列表推导式如何扮演循环和条件语 ...

  9. bzoj2012: [Ceoi2010]Pin

    Description 给出N(2<=N<=50000)个长度为4的字符串,问有且仅有D(1<=D<=4)处不相同的字符串有几对. Input 第1行: N,D 以下N行每行一 ...

  10. 二. log4j配置文件

    log4j的配置文件 # Output pattern : date [thread] priority category - message log4j.rootLogger=info,Consol ...