POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 56150 | Accepted: 19398 |
Description
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
from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.
Output
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/最长公共子序列+滚动数组)的更多相关文章
- POJ1159——Palindrome(最长公共子序列+滚动数组)
Palindrome DescriptionA palindrome is a symmetrical string, that is, a string read identically from ...
- POJ - 1458 Common Subsequence DP最长公共子序列(LCS)
Common Subsequence A subsequence of a given sequence is the given sequence with some elements (possi ...
- poj 1159 Palindrome(区间dp)
题目链接:http://poj.org/problem?id=1159 思路分析:对该问题的最优子结构与最长回文子序列相同.根据最长回文子序列的状态方程稍加改变就可以得到该问题动态方程. 假设字符串为 ...
- hdu 1159 Common Subsequence(最长公共子序列,DP)
题意: 两个字符串,判断最长公共子序列的长度. 思路: 直接看代码,,注意边界处理 代码: char s1[505], s2[505]; int dp[505][505]; int main(){ w ...
- poj1159--Palindrome(dp:最长公共子序列变形 + 滚动数组)
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 53414 Accepted: 18449 Desc ...
- hdu 1159 Common Subsequence(LCS最长公共子序列)
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- hdu1159 dp(最长公共子序列)
题意:给两个字符串,求这两个字符串的最长公共子序列的长度 因为之前集训的时候做过,所以现在即使会做也并不是什么稀奇的事,依旧为了自己的浅薄感到羞愧啊``` 解法就是通过两个字符串的每个字符互相比较,根 ...
- hdu 1159 Common Subsequence (最长公共子序列 +代码)
Problem Description A subsequence of a given sequence is the given sequence with some elements (poss ...
- hdu 1159 Common Subsequence(最长公共子序列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Jav ...
随机推荐
- Informatica 常用组件Aggregator之三 使用排序输入
可以使用排序输入选项改善聚合转换性能.使用排序输入时,PowerCenter 会假定所有数据已按组排序.PowerCenter 读取某组的行时,它将执行聚合计算.需要时,它会将组信息存储在存储器中.要 ...
- 我的SQL里哪个语句占用的CPU最多?
可以使用下面的语句来得到 SELECT SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1, ( (CASE qs.statement_end_off ...
- android_orm框架之greenDAO(一)
目录: 一.概述 二.下载并解压greenDAO相关资源 三.应用greenDAO框架 1.创建Java工程 2.添加类库支持 3.创建类 四.代码分析 五.使用greenDAO 六.源码下载 一.概 ...
- Android制作曲线、柱状图、饼形等图表——使用AChartEngine
之前在java开发中实现图表使用JFreeChar组件,最近有个小项目要求在Android端进行数据分析,如何实现图表呢?查了一下google提供了一个开源组件Achartengine非常好用,可实现 ...
- [转载]Elasticsearch索引重建(Rebuild)
From:http://blog.csdn.net/changong28/article/details/38491185 索引重建(Rebuild) 索引创建后,你可以在索引当中添加新的类型,在类型 ...
- PHP 解决版本问题:"Assigning the return value of new by reference is deprecated"
问题描述: 在最近使用ECSHOP v273帮客户建立了一个商城系统,商城搭建一切ok但在使用中后台发现了一个500错误 在服务器上访问该地址发现了错误信息:"Assigni ...
- 从Date类型字段获得当日周几的DAYNAME函数
例: select dayname(date) from pos.daywork
- C++ Linux 多线程之创建、管理线程
线程就是,在同一程序同一时间内同意运行不同函数的离散处理队列. 这使得一个长时间去进行某种特殊运算的函数在运行时不阻碍其它的函数变得十分重要. 线程实际上同意同一时候运行两种函数,而这两个函数不必相互 ...
- C#.NET常见问题(FAQ)-使用SharpDevelop开发 如何在项目中添加类文件
点击文件-新建-文件,然后再工程内创建文件 或者工程-添加-新建项 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com/acetaohai12 ...
- Visual Studio使用中的问题
1.后台断点调试,一到断点的时候就VS已停止 原因:安装插件问题,我的由于安装了" .NET Reflector Visual Studio Extension "插件 解决办法: ...