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> # ...
随机推荐
- OpenJudge计算概论-鸡兔同笼【新版题目,简单计算级别】
/*====================================================================== 鸡兔同笼 总时间限制: 1000ms 内存限制: 65 ...
- docker 数据共享,数据复制
docker 提供的数据共享的方式有 docker run -it -v:/dataname image 数据复制使用 docker cp containerid:/dataname ...
- Redis分布式部署,一致性hash
一致性哈希 由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,2^32-1]区间,如果我们把一个圆环用2^32 个点来进行均匀切割,首先按照hash( ...
- MongoDB权限管理之用户名和密码的操作
MongoDB默认是不需要输入用户名和密码,客户就可以登录的.但是出于安全性的考虑,我们还是要为其设置用户名和密码.本文主要介绍的是MongoDB权限管理之用户名和密码的操作,希望能对您有所帮助. 本 ...
- 【转】个人最常用的Eclipse快捷键
记录下自己在Eclipse中最常使用的快捷键: 其实网上总结多的是,自己记录下自己平时最切身受益的一些快捷键. 1.SHIFT+ ALT+Z(刚学的): 条件:选中一段代码 会弹出上面的右键菜单, ...
- 安卓模拟器安装apk,上网
1.首先找到安装安卓模拟器的文件夹: 2.目录:D:\Java\Android-all\platform-tools 3.运行cmd命令:adb install D:\Java\Android-all ...
- 查看SQL执行计划
一用户进入某界面慢得要死,查看SQL执行计划如下(具体SQL语句就不完全公布了,截断的如下): call count cpu elapsed disk ...
- android学习笔记47——读写SD卡上的文件
读写SD卡上的文件 通过Context的openFileInput.openFileOutput来打开文件输入流.输出流时,程序打开的都是应用程序的数据文件夹里的文件,其存储的文件大小可能都比较有限- ...
- android学习笔记25——事件处理Handler
Handler消息传递机制 ==> android消息机制是另一种形式的“事件处理”,这种机制主要是为了解决android应用的多线程问题. ——android平台不允许Activity新启动的 ...
- [linux basic 基础]----同步互斥量
互斥量,运行程序元锁住某个对象,使得每次只能有一个线程访问它:为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁它 :基本函数与用于信号量的函数非常相似#inclu ...