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 ...
随机推荐
- 构建一个高可扩展性javabean和jsp连接数据库操作
1. 我们先在Tomcat 中创建一个DataSource- jdbc/Panabia,然后再创建一个java“基类”,这个类封装了数据库连接和连接的释放. package Panabia.db; i ...
- maven依赖信息获取
1.mvn dependency:analyze 首先是"Used declared dependencies found",指项目中使用到,但是没有显示声明的依赖,如果有的话,需 ...
- 【BZOJ】【2850】【Violet 0】巧克力王国
KD-Tree 问平面内在某条直线下方的点的权值和 我一开始yy的是:直接判这个矩形最高的两个点(y坐标的最大值)是否在这条直线下方就可以了~即判$A*x+B*y<C$... 然而这并不对啊…… ...
- AndEngine中文文档下载地址
AndEngine doc downloadhere 下载地址:http://pan.baidu.com/s/1bnjcL0V 文档是由github仓库AndEngine的代码生成. 本doc中包括 ...
- QT学习:c++解析html相关
原来我做爬虫的时候,对页面进行解析的时候总是用很简单粗暴的方法,直接找规律.后来在网上看到了gumbo,尝试了一下,发现确实很好用,所以向大家推荐一下. 以下转自:http://blog.csdn.n ...
- 第八章 JVM性能监控与故障处理工具(2)
注意:该篇博客主要记录自<深入理解java虚拟机(第二版)> 说明:关于命令行的JVM性能监控与故障处理工具见<第七章 JVM性能监控与故障处理工具(1)> 1.图像化的故障处 ...
- Aliasing input/output properties
angular @input alias别名的使用. https://angular.io/guide/template-syntax#aliasing-io https://stackoverflo ...
- python下载文件的三种方法
Python开发中时长遇到要下载文件的情况,最常用的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib从ftp站点下载文件.此外Python还提供了另外一种方法 ...
- Codeforces#86D Powerful array(分块暴力)
Description An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary su ...
- C# WebRequest处理Https请求
http://www.cnblogs.com/youlechang123/archive/2013/03/23/2976630.html 正常情况下,处理https和http没有什么区别,如以下代码, ...