POJ - 1159 Palindrome(dp-回文变形)
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-回文变形)的更多相关文章
- POJ 3280 Cheapest Palindrome(DP 回文变形)
题目链接:http://poj.org/problem?id=3280 题目大意:给定一个字符串,可以删除增加,每个操作都有代价,求出将字符串转换成回文串的最小代价 Sample Input 3 4 ...
- poj 3280 Cheapest Palindrome ---(DP 回文串)
题目链接:http://poj.org/problem?id=3280 思路: dp[i][j] :=第i个字符到第j个字符之间形成回文串的最小费用. dp[i][j]=min(dp[i+1][j]+ ...
- HDU 1513 && POJ 1159 Palindrome (DP+LCS+滚动数组)
题意:给定一个字符串,让你把它变成回文串,求添加最少的字符数. 析:动态规划是很明显的,就是没有了现思路,还是问的别人才知道,哦,原来要么写,既然是回文串, 那么最后正反都得是一样的,所以我们就正反求 ...
- poj 1159 Palindrome(dp)
题目:http://poj.org/problem?id=1159 #include<iostream> #include<cstring> #include<cstdi ...
- poj 1159 最长回文
方法 LCS #include<iostream> #include<cstring> #include<algorithm> #include<stdio ...
- POJ 1159 Palindrome(字符串变回文:LCS)
POJ 1159 Palindrome(字符串变回文:LCS) id=1159">http://poj.org/problem? id=1159 题意: 给你一个字符串, 问你做少须要 ...
- CF932G Palindrome Partition(回文自动机)
CF932G Palindrome Partition(回文自动机) Luogu 题解时间 首先将字符串 $ s[1...n] $ 变成 $ s[1]s[n]s[2]s[n-1]... $ 就变成了求 ...
- [LeetCode] Valid Palindrome 验证回文字符串
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...
- dp回文
.dp回文子串 通常在dp数组中存放的是 从i到j是否是回文子串 1.动态规划 2.中心扩展法 #include<iostream> #include<algorithm> # ...
随机推荐
- Jquery遍历元素
页面中所有的checkBox遍历: <script type="text/javascript" src="/jquery/jquery.js">& ...
- 全局程序集GlobalAssemblyInfo.cs进行版本控制(引)
原文出自:http://blog.csdn.net/oyi319/article/details/5753311 1.全局程序集GlobalAssemblyInfo.cs 我们编写的一个解决方案,通常 ...
- spring data redis RedisTemplate操作redis相关用法
http://blog.mkfree.com/posts/515835d1975a30cc561dc35d spring-data-redis API:http://docs.spring.io/sp ...
- SqlServer数据库正在还原的解决办法
1)管理器不会主动刷新,需要手工刷新一下才能看到最新状态(性能方面的考虑) 2)很少情况下,恢复进程被挂起了.这个时候假设你要恢复并且回到可访问状态,要执行: RESTORE database ...
- LintCode "Expression Evaluation"
This is sth. for me to learn.. https://github.com/kamyu104/LintCode/blob/master/C++/expression-evalu ...
- 【转】Linux 的启动流程
半年前,我写了<计算机是如何启动的?>,探讨BIOS和主引导记录的作用. 那篇文章不涉及操作系统,只与主板的板载程序有关.今天,我想接着往下写,探讨操作系统接管硬件以后发生的事情,也就是操 ...
- MySQL数据库MyISAM和InnoDB存储引擎的比较
MySQL有多种存储引擎,MyISAM和InnoDB是其中常用的两种.这里介绍关于这两种引擎的一些基本概念(非深入介绍). MyISAM是MySQL的默认存储引擎,基于传统的ISAM类型,支持全文搜索 ...
- android学习笔记29——Intent/IntentFilter
Intent/IntentFilter Intent封装android应用程序需要启动某个组件的“意图”,Intent还是应用程序组件之间通信的重要媒介. EG:Activity之间需要交换数据时,使 ...
- SQLite加密的方法(c#)
http://blog.csdn.net/xjbx/article/details/2712236 设置下密码就可以了 http://bbs.csdn.net/topics/380018685 编译为 ...
- SQLServer数据库字典维护方法
启用SQLServer启用管理器,以2008为例 1.设置表信息描述 选中要设置的表,右键点击“属性” . 选择扩展属性 填写要求: 名称:MS_Description 值: 模块名称-表名称 修改语 ...