题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513

题意:

  给你一个字符串s,你可以在s中的任意位置添加任意字符,问你将s变成一个回文串最少需要添加字符的个数。

题解1(LCS):

  很神奇的做法。

  先求s和s的反串的LCS,也就是原串中已经满足回文性质的字符个数。

  然后要变成回文串的话,只需要为剩下的每个落单的字符,相应地插入一个和它相同的字符即可。

  所以答案是:s.size()-LCS(s,rev(s))

  另外,求LCS时只会用到lcs[i-1][j-1],lcs[i-1][j],lcs[i][j-1],因为空间不够,改为滚动数组,将第一维[MAX_N]变为[2]。

题解2(记忆化搜索):

  做法是对的,但是空间占用太大,会MLE。

  dfs(x,y)表示让s串中[x,y]这个区间变为回文串的花费。

  两种情况:

    (1)s[x]==s[y]:

        s[x]和s[y]已经配对,所以return dfs(x+1,y-1);

    (2)s[x]!=s[y]:

        有两种解决办法:

          1.让[x+1,y]变为回文串,然后在y的右边添加一个字符等于s[x]。

          2.让[x,y-1]变为回文串,然后在x的左边添加一个字符等于s[y]。

        所以return min(dfs(x+1,y),dfs(x,y-1))+1;

  判断dfs结束边界:

    (1)dp[x][y]!=-1:之前已经算过了,那就不用再算一遍了,return dp[x][y]。

    (2)x==y: return 0;

    (3)x+1==y: 如果s[x]==s[y],return 0;如果s[x]!=s[y],return 1;

  另外,每次dfs算出新的dp时,及时保存到dp数组中。

AC Code:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <algorithm>
  5. #define MAX_N 5005
  6.  
  7. using namespace std;
  8.  
  9. int n;
  10. int dp[][MAX_N];
  11. string s;
  12.  
  13. int lcs(string a,string b)
  14. {
  15. memset(dp,,sizeof(dp));
  16. for(int i=;i<=a.size();i++)
  17. {
  18. for(int j=;j<=b.size();j++)
  19. {
  20. if(a[i-]==b[j-]) dp[i&][j]=dp[(i-)&][j-]+;
  21. else dp[i&][j]=max(dp[(i-)&][j],dp[i&][j-]);
  22. }
  23. }
  24. return dp[a.size()&][b.size()];
  25. }
  26.  
  27. int palindrome(string s)
  28. {
  29. string rev=s;
  30. reverse(rev.begin(),rev.end());
  31. return s.size()-lcs(s,rev);
  32. }
  33.  
  34. int main()
  35. {
  36. while(cin>>n>>s)
  37. {
  38. cout<<palindrome(s)<<endl;
  39. }
  40. }

没AC Code:

  1. // dp[x][y] = min num of chars appended to s
  2. // dp[x][x] = 0
  3. //
  4. // 1) s[i] != s[j]:
  5. // dp[x][x+1] = 1
  6. // dp[x][y] = min(dp[x+1][y], dp[x][y-1]) + 1
  7. //
  8. // 2) s[i] == s[j]
  9. // dp[x][y] = dp[x+1][y-1]
  10.  
  11. #include <iostream>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #define MAX_N 5005
  15.  
  16. using namespace std;
  17.  
  18. int n;
  19. int dp[MAX_N][MAX_N];
  20. string s;
  21.  
  22. int dfs(int x,int y)
  23. {
  24. if(dp[x][y]!=-) return dp[x][y];
  25. if(x==y) return dp[x][y]=;
  26. if(x+==y) return dp[x][y]=(s[x]==s[y]?:);
  27. if(s[x]==s[y]) return dp[x][y]=dfs(x+,y-);
  28. return dp[x][y]=min(dfs(x+,y),dfs(x,y-))+;
  29. }
  30.  
  31. int main()
  32. {
  33. while(cin>>n>>s)
  34. {
  35. memset(dp,-,sizeof(dp));
  36. cout<<dfs(,s.size()-)<<endl;
  37. }
  38. }

HDU 1513 Palindrome:LCS(最长公共子序列)or 记忆化搜索的更多相关文章

  1. HDU 1513 Palindrome(最长公共子序列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 解题报告:给定一个长度为n的字符串,在这个字符串中插入最少的字符使得这个字符串成为回文串,求这个 ...

  2. 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...

  3. POJ 1458 Common Subsequence(LCS最长公共子序列)

    POJ 1458 Common Subsequence(LCS最长公共子序列)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?c ...

  4. 动态规划模板2|LCS最长公共子序列

    LCS最长公共子序列 模板代码: #include <iostream> #include <string.h> #include <string> using n ...

  5. LCS 最长公共子序列

    区别最长公共子串(连续) ''' LCS 最长公共子序列 ''' def LCS_len(x, y): m = len(x) n = len(y) dp = [[0] * (n + 1) for i ...

  6. HDU 1159 Common Subsequence 最长公共子序列

    HDU 1159 Common Subsequence 最长公共子序列 题意 给你两个字符串,求出这两个字符串的最长公共子序列,这里的子序列不一定是连续的,只要满足前后关系就可以. 解题思路 这个当然 ...

  7. hdu 1159 Common Subsequence(LCS最长公共子序列)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  8. LCS最长公共子序列~dp学习~4

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 Palindrome Time Limit: 4000/2000 MS (Java/Others ...

  9. LCS最长公共子序列(最优线性时间O(n))

    这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...

  10. LCS最长公共子序列

    问题:最长公共子序列不要求所求得的字符串在所给字符串中是连续的,如输入两个字符串ABCBDAB和BDCABA,字符串BCBA和BDAB都是他们的公共最长子序列 该问题属于动态规划问题 解答:设序列X= ...

随机推荐

  1. 6位密码框js

    !DOCTYPE html><html> <head> <meta http-equiv="Content-Type" content=&quo ...

  2. Azure MySQL PaaS (3) 创建MySQL异地只读数据库 (Master-Slave)

    <Windows Azure Platform 系列文章目录> Azure MySQL PaaS服务提供异地只读的功能,我们可以在主站点,比如Azure上海数据中心,创建MySQL主节点. ...

  3. QQ信鸽推送

    闲来无事,看看腾讯的信鸽推送! 优点: 1.毕竟大腿出的东西,不会太差 2.集成快 3.推送效率高,功能强,APP后台被杀的情况下同样能接受到推送. 废话少说,直接上代码: 源代码.zip

  4. Educational Codeforces Round 22.B 暴力

    B. The Golden Age time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  5. (转载)Java多线程的监控分析工具(VisualVM)

    原文链接:http://blog.csdn.net/chendc201/article/details/22905511 在Java多线程程序运行时,多数情况下我们不知道到底发生了什么,只有出了错误的 ...

  6. Japanese Learning - Words and Sentences 1

    1. いらっしゃいませ.何名さまですか. 二人です. タバコをお吸いになりますか. かしこまりました.少々お待ちください. お勘定お願いします. ご一緒でよろしいでしょうか. 別々にお願いします. 2 ...

  7. Java纸牌小demo以及日历小demo

    //卡牌类 public class Card { //定义卡牌的点数 public static final String[] cardName = { "3", "4 ...

  8. Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(三)技能标签(Ability Tags)

    本教程参考了https://wiki.unrealengine.com/GameplayAbilities_and_You,如果没有学习前两篇教程,请前往学习. GameplayAbilities插件 ...

  9. Sping之Ioc

    Ioc,控制反转,依赖注入! 作用:降低代码之间的耦合性 代码永远是最好的示例: 1.新建test类 package demo; public class test { String string_v ...

  10. 不借助工具在浏览器中通过Web API执行Dynamics 365操作(Action)实例

    摘要: 本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复262或者20170727可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyon ...