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

  1. /*
  2. 用short险过
  3.  
  4. dp[i][j]表示原串前i个字符与逆序串前j个字符的最长公共子序列
  5.  
  6. if(str[i-1]==str2[j-1]){
  7. dp[i][j]=dp[i-1][j-1]+1;
  8. }
  9. else{
  10. dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
  11. }
  12.  
  13. */
  14. #include<iostream>
  15. #include<stdio.h>
  16. #include<string.h>
  17. using namespace std;
  18.  
  19. #define MAXN 5005
  20.  
  21. short dp[MAXN][MAXN];
  22. char str[MAXN],str2[MAXN];
  23.  
  24. int main(){
  25.  
  26. int N;
  27. int i,j;
  28.  
  29. while(~scanf("%d",&N)){
  30.  
  31. scanf("%s",str);
  32.  
  33. for(i=,j=N-;i<N;++i,--j){
  34. str2[i]=str[j];
  35. }
  36.  
  37. memset(dp,,sizeof(dp));
  38. for(i=;i<=N;++i){
  39. for(j=;j<=N;++j){
  40. if(str[i-]==str2[j-]){
  41. dp[i][j]=dp[i-][j-]+;
  42. }
  43. else{
  44. dp[i][j]=max(dp[i-][j],dp[i][j-]);
  45. }
  46. }
  47. }
  48.  
  49. printf("%d\n",N-dp[N][N]);
  50. }
  51.  
  52. return ;
  53. }

ps:其实可以用滚动数组

c'.滚动数组

  1. /*
  2. 用short险过
  3.  
  4. dp[i][j]表示原串前i个字符与逆序串前j个字符的最长公共子序列
  5.  
  6. if(str[i-1]==str2[j-1]){
  7. dp[i][j]=dp[i-1][j-1]+1;
  8. }
  9. else{
  10. dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
  11. }
  12.  
  13. */
  14. #include<iostream>
  15. #include<stdio.h>
  16. #include<string.h>
  17. using namespace std;
  18.  
  19. #define MAXN 5005
  20.  
  21. short dp[][MAXN];//滚动数组
  22. char str[MAXN],str2[MAXN];
  23.  
  24. int main(){
  25.  
  26. int N;
  27. int i,j;
  28.  
  29. while(~scanf("%d",&N)){
  30.  
  31. scanf("%s",str);
  32.  
  33. for(i=,j=N-;i<N;++i,--j){
  34. str2[i]=str[j];
  35. }
  36.  
  37. memset(dp,,sizeof(dp));
  38. for(i=;i<=N;++i){
  39. for(j=;j<=N;++j){
  40. if(str[i-]==str2[j-]){
  41. dp[i%][j]=dp[(i-)%][j-]+;
  42. }
  43. else{
  44. dp[i%][j]=max(dp[(i-)%][j],dp[i%][j-]);
  45. }
  46. }
  47. }
  48.  
  49. printf("%d\n",N-dp[N%][N]);
  50. }
  51.  
  52. return ;
  53. }

c2.法2

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. using namespace std;
  5.  
  6. #define MAXN 5005
  7.  
  8. short dp[MAXN][MAXN];
  9. char str[MAXN];
  10.  
  11. int main(){
  12.  
  13. int N;
  14. int i,j;
  15.  
  16. while(~scanf("%d",&N)){
  17. scanf("%s",str);
  18.  
  19. memset(dp,,sizeof(dp));
  20.  
  21. for(i=N-;i>=;--i){
  22. dp[i][i]=;
  23. for(j=i+;j<N;++j){
  24. if(str[i]==str[j]){
  25. dp[i][j]=dp[i+][j-];
  26. }
  27. else{
  28. dp[i][j]=min(dp[i+][j],dp[i][j-])+;
  29. }
  30. }
  31. }
  32.  
  33. printf("%d\n",dp[][N-]);
  34. }
  35.  
  36. return ;
  37. }

c2'.滚动数组

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. using namespace std;
  5.  
  6. #define MAXN 5005
  7.  
  8. short dp[][MAXN];//滚动数组
  9. char str[MAXN];
  10.  
  11. int main(){
  12.  
  13. int N;
  14. int i,j;
  15.  
  16. while(~scanf("%d",&N)){
  17. scanf("%s",str);
  18.  
  19. memset(dp,,sizeof(dp));
  20.  
  21. for(i=N-;i>=;--i){
  22. dp[i%][i%]=;
  23. for(j=i+;j<N;++j){
  24. if(str[i]==str[j]){
  25. dp[i%][j]=dp[(i+)%][j-];
  26. }
  27. else{
  28. dp[i%][j]=min(dp[(i+)%][j],dp[i%][j-])+;
  29. }
  30. }
  31. }
  32.  
  33. printf("%d\n",dp[][N-]);
  34. }
  35.  
  36. return ;
  37. }

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. OpenJudge计算概论-鸡兔同笼【新版题目,简单计算级别】

    /*====================================================================== 鸡兔同笼 总时间限制: 1000ms 内存限制: 65 ...

  2. docker 数据共享,数据复制

    docker 提供的数据共享的方式有 docker   run  -it  -v:/dataname  image 数据复制使用 docker  cp  containerid:/dataname   ...

  3. Redis分布式部署,一致性hash

    一致性哈希 由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,2^32-1]区间,如果我们把一个圆环用2^32 个点来进行均匀切割,首先按照hash( ...

  4. MongoDB权限管理之用户名和密码的操作

    MongoDB默认是不需要输入用户名和密码,客户就可以登录的.但是出于安全性的考虑,我们还是要为其设置用户名和密码.本文主要介绍的是MongoDB权限管理之用户名和密码的操作,希望能对您有所帮助. 本 ...

  5. 【转】个人最常用的Eclipse快捷键

      记录下自己在Eclipse中最常使用的快捷键: 其实网上总结多的是,自己记录下自己平时最切身受益的一些快捷键. 1.SHIFT+ ALT+Z(刚学的): 条件:选中一段代码 会弹出上面的右键菜单, ...

  6. 安卓模拟器安装apk,上网

    1.首先找到安装安卓模拟器的文件夹: 2.目录:D:\Java\Android-all\platform-tools 3.运行cmd命令:adb install D:\Java\Android-all ...

  7. 查看SQL执行计划

    一用户进入某界面慢得要死,查看SQL执行计划如下(具体SQL语句就不完全公布了,截断的如下): call     count       cpu    elapsed       disk       ...

  8. android学习笔记47——读写SD卡上的文件

    读写SD卡上的文件 通过Context的openFileInput.openFileOutput来打开文件输入流.输出流时,程序打开的都是应用程序的数据文件夹里的文件,其存储的文件大小可能都比较有限- ...

  9. android学习笔记25——事件处理Handler

    Handler消息传递机制 ==> android消息机制是另一种形式的“事件处理”,这种机制主要是为了解决android应用的多线程问题. ——android平台不允许Activity新启动的 ...

  10. [linux basic 基础]----同步互斥量

    互斥量,运行程序元锁住某个对象,使得每次只能有一个线程访问它:为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁它 :基本函数与用于信号量的函数非常相似#inclu ...