Palindrome
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 56150   Accepted: 19398

Description

A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order
to obtain a palindrome. 



As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome. 

Input

Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from 'A' to 'Z', lowercase letters
from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.

Output

Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.

Sample Input

5
Ab3bd

Sample Output

2

给一个字符串,计算最少加多少个字符可以使字符串变成回文串(即从前往后读与从后往前读一样)。

有2种思路。一种是直接区间DP。dp[j][i]表示[i,j]这个子串要变成回文串须要加入多少个字符,状态转移方程例如以下:

if(s[i]==s[j])                           

    dp[j][i]=dp[j+1][i-1];

else

    dp[j][i]=1+min(min[j+1][i],min[j][i-1])

另外一种思路也比較easy想,要将一个字符串变为回文串,那么我们就能够先得到这个字符串的逆序串,然后再求出这两个的最长公共子序列,要加入的字符数就是字符串长度减去最长公共子序列的长度。

另外,这道题还会限制内存。

假设定义一个5000*5000的数组会Memory Limit Exceeded。有两种解决方式。一是把数组定义成short型。这样原本的内存会降低非常大一部分,大概会在50000kb左右,刚好可以AC;还有一种解决方式:由于计算第i行时仅仅须要知道第i-1行。所以可以开一个2*5000的滚动dp数组。这样的方法比較推荐。非常节省内存。

/*
LCS+short
Memory: 49688 KB Time: 1094 MS
Language: G++ Result: Accepted
*/
#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma commment(linker,"/STACK: 102400000 102400000")
#define lson a,b,l,mid,cur<<1
#define rson a,b,mid+1,r,cur<<1|1
using namespace std;
const double eps=1e-6;
const int MAXN=5001; char s[MAXN],t[MAXN];
int n,ans,tlen;
short int dp[MAXN][MAXN]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d",&n)!=EOF)
{
scanf("%s",s+1);
for(int i=n;i>=1;i--)
t[n-i+1]=s[i];
t[n+1]=0;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(s[i]==t[j])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
printf("%d\n",n-dp[n][n]);
}
return 0;
}
/*
DP+short
Memory: 55716 KB Time: 1454 MS
Language: G++ Result: Accepted
*/
#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma commment(linker,"/STACK: 102400000 102400000")
#define lson a,b,l,mid,cur<<1
#define rson a,b,mid+1,r,cur<<1|1
using namespace std;
const double eps=1e-6;
const int MAXN=5300; char s[MAXN];
short int n,dp[MAXN][MAXN]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d",&n)!=EOF)
{
scanf("%s",s);
memset(dp,0,sizeof(dp));
for(int i=1;i<n;i++)
for(int j=i-1;j>=0;j--)
{
if(s[i]==s[j])
dp[j][i]=dp[j+1][i-1];
else
dp[j][i]=(short int)(min(dp[j+1][i],dp[j][i-1])+1);
}
printf("%d\n",dp[0][n-1]);
}
return 0;
}
/*
LCS+滚动数组
Memory: 728 KB Time: 735 MS
Language: G++ Result: Accepted
*/
#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma commment(linker,"/STACK: 102400000 102400000")
#define lson a,b,l,mid,cur<<1
#define rson a,b,mid+1,r,cur<<1|1
using namespace std;
const double eps=1e-6;
const int MAXN=5001; char s[MAXN],t[MAXN];
int n,ans,tlen,dp[2][MAXN]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d",&n)!=EOF)
{
scanf("%s",s+1);
for(int i=n; i>=1; i--)
t[n-i+1]=s[i];
t[n+1]=0;
memset(dp,0,sizeof(dp));
int indexs=0;
for(int i=1; i<=n; i++)
{
indexs=!indexs;
for(int j=1; j<=n; j++)
if(s[i]==t[j])
dp[indexs][j]=dp[!indexs][j-1]+1;
else
dp[indexs][j]=max(dp[!indexs][j],dp[indexs][j-1]);
}
printf("%d\n",n-dp[indexs][n]);
}
return 0;
}

POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)的更多相关文章

  1. POJ1159——Palindrome(最长公共子序列+滚动数组)

    Palindrome DescriptionA palindrome is a symmetrical string, that is, a string read identically from ...

  2. POJ - 1458 Common Subsequence DP最长公共子序列(LCS)

    Common Subsequence A subsequence of a given sequence is the given sequence with some elements (possi ...

  3. poj 1159 Palindrome(区间dp)

    题目链接:http://poj.org/problem?id=1159 思路分析:对该问题的最优子结构与最长回文子序列相同.根据最长回文子序列的状态方程稍加改变就可以得到该问题动态方程. 假设字符串为 ...

  4. hdu 1159 Common Subsequence(最长公共子序列,DP)

    题意: 两个字符串,判断最长公共子序列的长度. 思路: 直接看代码,,注意边界处理 代码: char s1[505], s2[505]; int dp[505][505]; int main(){ w ...

  5. poj1159--Palindrome(dp:最长公共子序列变形 + 滚动数组)

    Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 53414   Accepted: 18449 Desc ...

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

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

  7. hdu1159 dp(最长公共子序列)

    题意:给两个字符串,求这两个字符串的最长公共子序列的长度 因为之前集训的时候做过,所以现在即使会做也并不是什么稀奇的事,依旧为了自己的浅薄感到羞愧啊``` 解法就是通过两个字符串的每个字符互相比较,根 ...

  8. hdu 1159 Common Subsequence (最长公共子序列 +代码)

    Problem Description A subsequence of a given sequence is the given sequence with some elements (poss ...

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Jav ...

随机推荐

  1. [MAC OS] NSButton tag 获取

    @IBAction func switchContentLayout(_ sender: Any) { let button : NSButton = sender as! NSButton;}

  2. 不明白的sizeof(enum)数据结构存储问题

    不明白的sizeof(enum)数据结构存储问题 typedef struct weekday_st { enum week {sun=123456789,mon,tue,wed,thu,fri,sa ...

  3. 完全理解Gson(1):简单入门

    GSON是Google开发的Java API,用于转换Java对象和Json对象.本文讨论并提供了使用API的简单代码示例.更多关于GSON的API可以访问:http://sites.google.c ...

  4. JDBC操作数据库的批处理

    在JDBC开发中,操作数据库需要与数据库建立连接,然后将要执行的SQL语句传送到数据库服务器,最后关闭数据库连接,都是按照这样一个流程进行操作的.如果按照该流程执行多条SQL语句,那么就需要建立多个数 ...

  5. iOS:UIScrollView控件和UIPageControl控件的详解

    UIScrollView滚动视图控件和UIPageControl分页视图控件:    UIScrollView用于显示多于一个屏幕的内容,超出屏幕范围的内容可以通过滑动进行查看,当然UIPagecon ...

  6. [12] 扇形体(Fan)图形的生成算法

    顶点数据的生成 bool YfBuildFunVertices ( Yreal radius, Yreal degree, Yreal height, Yuint slices, YeOriginPo ...

  7. 第四章 mybatis批量insert

    批量插入sql语句: INSERT INTO table (field1,field2,field3) VALUES ('a',"b","c"), ('a',& ...

  8. OkHttp 官方Wiki之【使用案例】

    原文位置:https://github.com/square/okhttp/wiki/Recipes Recipes 食谱/知识点清单 We've written some recipes that ...

  9. 【属性动画总结】Property Animation

    属性动画概述 3.0以前,android仅支持两种动画模式,tweened animation 和 frame-by-frame animation,在android3.0中又引入了一个新的动画系统: ...

  10. State 状态模式 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...