题目:http://poj.org/problem?id=1159

思路:

找出原串的最长回文子串,当然这里说的回文子串可以不连续。用原串的长度减去最长回文子串的长度即可得出结果。

设原串a[5001],它的反串为b[5001],求出a和b的最长公共子串的长度(可以不连续),即为回文子串的长度。再用原串长度减去回文子串的长度即可。

用动态规划求公共子串的长度,m[5001][5001]打表。m[i][j]表示原串a第1个到第i个和反串b第1个到第j个的最长公共子串的长度。所以有两种情况:

(1)当a[i] = b[j]时,m[i][j]=m[i-1][j-1] + 1;

(2) a[i] != b[j]时,m[i][j]=max(m[i-1][j],m[i][j-1])。

所以m[len][len]就是最长公共子串的长度。(len为原串的长度)

算法正确性证明:

比如abcdb,最长回文串是bcb或bdb,长度是3,5-3=2,所以只需插入2个即可。为什么呢???

因为回文串有两种形式aba或者abba,我们暂且把后面那两个b看成是一个,这个没关系的,便于解释。那么一个字符串就分成了两类字符了,一个是回文串,一个是非回文串,假设把回文串的中间那个字符记成b,那么b左边的非回文串和b右边的非回文串就不可能有交集(如果有,那交集部分就会归并到回文串里),所以只需要在左边对称位置插入b右边的非回文字符,在右边插入b左边的非回文字符。所以要插入的字符个数就是非回文字符的个数,非回文字符就是回文字符串对原字符串的补集,故原串长度减去回文串长度即可得解。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 5001char a[N],b[N];unsigned short m[N][N];int main()
{int len,i,j,t;while(scanf("%d",&len) != EOF ){scanf("%s",a);                       t = len -1;for(i = len-1; i >= 0 ; --i)b[t-i] = a[i] ;for(i = 1 ; i <= len ; ++i)for(j = 0 ; j < i ; ++j)   m[i][j] = m[j][i] = 0;for(i = 0 ; i <= len ; ++i)m[i][i] = 0;for(i = 1 ; i <= len ; ++i){for(j = 1 ; j <= len ; ++j){if(a[i-1] == b[j-1])m[i][j] = m[i-1][j-1] + 1;elsem[i][j] = m[i-1][j] > m[i][j-1] ? m[i-1][j]:m[i][j-1];}}printf("%d\n",len - m[len][len]);} // system("pause");return 0;
}

开始用 int m[N][N]; 超内存了!用unsigned short 就AC了。

看discuss,人家用滚动数组!汗,落伍了。第一次听说这玩意,于是诚信学习了啊!

先贴个最简单的滚动数组的应用:(求Fabonacci数列的第100个数)

int d[3];
d[0]=1;d[1]=1;
for(i=2;i<100;i++)
d[i%3]=d[(i-1)%3]+d[(i-2)%3];
printf("%d",d[99%3]);
注意上面的运算,我们只留了最近的3个解,数组好象在“滚动‿一样,所以叫滚动数组。

好了,这个题就可以用滚动数组+DP AC了。用一个二位的数组m[2][N]。列可以往后展开,行不停的滚动,

滚动方式: i%2,(i-1)%2

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 5001unsigned short m[2][N];
char a[N],b[N];int main()
{int len,i,j,t;while(scanf("%d",&len) != EOF ){scanf("%s",a);                       t = len -1;for(i = len-1; i >= 0 ; --i)b[t-i] = a[i] ;for(i = 0 ; i <= len ; ++i)   m[0][i] = m[1][i] = 0;for(i = 1 ; i <= len ; ++i){for(j = 1 ; j <= len ; ++j){if(a[i-1] == b[j-1])m[i%2][j] = m[(i-1)%2][j-1] + 1;elsem[i%2][j] = m[(i-1)%2][j] > m[i%2][j-1] ? m[(i-1)%2][j]:m[i%2][j-1];}}printf("%d\n",len - m[len%2][len]);               } //system("pause");return 0;
}

转载于:https://www.cnblogs.com/HpuAcmer/archive/2012/05/03/2481323.html

POJ 1159 (DP)相关推荐

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

    POJ 1159 Palindrome(字符串变回文:LCS) http://poj.org/problem? id=1159 题意: 给你一个字符串, 问你做少须要在该字符串中插入几个字符能是的它变 ...

  2. POJ 3017 DP + 单调队列 + 堆

    题意:给你一个长度为n的数列,你需要把这个数列分成几段,每段的和不超过m,问各段的最大值之和的最小值是多少? 思路:dp方程如下:设dp[i]为把前i个数分成合法的若干段最大值的最小值是多少.dp转移 ...

  3. POJ 1037 DP

    题目链接: http://poj.org/problem?id=1037 分析: 很有分量的一道DP题!!! (参考于:http://blog.csdn.net/sj13051180/article/ ...

  4. POJ 1661 DP

    Help Jimmy Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11071   Accepted: 3607 Descr ...

  5. POJ 3666 dp

    题意 传送门 POJ 3666 基本思路是对 N 个位置枚举所有可能高度,并 dp 求最大值.可能高度取 N 个位置的高度即可,排序以方便顺序 dp.对于升序的情况 dp[i][j]=max{dp[i ...

  6. POJ 3666(DP)

    题目链接:http://poj.org/problem?id=3666 题目大意:给一个串,要求修改最少使得串满足非递增或非递减 题目思路:刚开始没想到,后来经学长提醒如果串里的数字变1000可以怎么 ...

  7. POJ 3257 DP

    题意: 思路: 用vector存上本出发点能到的地方&成本&有趣指数(用结构体保存) 然后DP就好了 f[i][j]表示到了i 成本为j的有趣指数最大是多少 f[vec[i][k].e ...

  8. poj 2392 dp 不是很懂哎!!!Space Elevator

    大意:有K种block去建塔,每种每个都有一个高度H,用了当前的block塔的高度不能超出a,和每种的数量.求塔最高能建多高. 分析:这题就是一个多重背包,但有一点变动,必须先以a从小到大排序,因为如 ...

  9. poj 2346(DP)

     题意:n位数,满足前n/2个数字之和同后n/2个数字之和相同的数一共有多少个? 解题思路:dp[i][j]表示前i个数的和为j时,有多少个: 递推关系:dp[i][j] += dp[i-1][k ...

最新文章

  1. 循环链表(约瑟夫环)的建立及C语言实现
  2. 056_Unicode字符官方标准七
  3. Windows中的命令行提示符里的Start命令执行路径包含空格时的问题
  4. 不知怎么优化MySQL?先搞懂原理再说吧!
  5. 7.1使用Request获取HTTP请求头
  6. CBO Cost Formulas基于成本优化器的成本计算公式大全
  7. 为啥饮料瓶大都是圆的,牛奶盒却是方的?
  8. 数据库操作,内外联查询,分组查询,嵌套查询,交叉查询,多表查询,语句小结...
  9. 马哥学习李洋个人笔记之-----正则表达式
  10. JAVA中常用接口的介绍及使用示例 java lang Comparable
  11. java服务器返回错误码,java - java.io.IOException:服务器返回URL的HTTP响应代码:409 - 堆栈内存溢出...
  12. php 智能输入提示插件,PHP结合jQuery.autocomplete插件实现输入自动完成提示的功能_PHP...
  13. ros学习-中国大学MOOC---《机器人操作系统入门》课程讲义
  14. 宽度学习(Broad Learning System)
  15. scratch编程三级--小猫和笔合作画正方形
  16. 如何开启QQ在线客服
  17. 86版五笔单字效率分析
  18. 【大连理工大学】计算机专业选修:深度学习2020期末复习
  19. MySQL的关键技术及主要特征_生物特征识别十大关键技术解析
  20. 力扣 838. 推多米诺

热门文章

  1. 二极管的结构、特性、参数、稳压管的特性和参数
  2. 2018.9.15,Arduino—流水灯实验报告
  3. java基于ssm的个人博客系统_调研了 100 来个 Java 博客系统,发现这5个最好用
  4. python数据分析函数大全_python中数据分析常用函数整理
  5. 使用try-catch-finally处理异常---java
  6. linux 内核入口地址,linux内核的加载地址和入口地址
  7. c语言程序设计报告用于医院食品加工等部,南开(本部)《C语言程序设计》14春在线作业答案...
  8. 电脑有回声_电脑连接麦克风有回音怎么办?麦克风回声的解决方法
  9. unicode解码php,PHP解码unicode编码的中文字符
  10. anaconda下python中matplotlib画图无法显示中文