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 ...
随机推荐
- 【spring cloud】【docker】使用docker在centOS上部署spring cloud微服务架构服务
项目GitHub地址 ================================================================================== 部署过程: ...
- remotepath != null 与 !TextUtils.isEmpty(remotepath) 的差别
remotepath != null 与 !TextUtils.isEmpty(remotepath) 的差别 !TextUtils.isEmpty(remotepath) 与 remo ...
- 利用Squid + DNSPOD 搭建CDN服务器
首先下载squid for windows安装包 squid-2.7.STABLE5-bin.zip 然后解压缩,放到C盘squid目录内. 进入目录C:\squid\etc内,将所有文件的.defa ...
- Spring Data Jpa 查询返回自定义对象
转载请注明出处:http://www.wangyongkui.com/java-jpa-query. 今天使用Jpa遇到一个问题,发现查询多个字段时返回对象不能自动转换成自定义对象.代码如下: //U ...
- 基于nginx实现protobuf RPC
老婆一起来上海工作,每个月消费立马上来了,做了一个android记账应用,把每笔帐都实时记录进去.开始是单机版的,只能两个人分别记,月底再merge一下.刚好有一台阿里云的ECS,于是准备升级为带服务 ...
- zookeeper 伪分布式安装
1 下载zookeeper安装包 下载地址 http://apache.fayea.com/zookeeper/ 我下载的是zookeeper-3.4.6.tar.gz 2 解压缩 将zookeepe ...
- iOS开发-UITableView常用方法
UITableView常用来展示数据,类似于Android中的ListView,相对于Android中的ListView而言,UITableView的实现是非常简单,继承UITableViewData ...
- ADB用法
作为android开发人员,adb是常用的工具之一.具体怎么使用了. 1. 安装完ADB后(ADB的安装请参考<Android开发平台搭建及配置.doc>),用电脑USB连接机器,然后使用 ...
- 手写一个自己的LocalCache - 基于LinkedHashMap实现LRU
功能目标 实现一个全局范围的LocalCache,各个业务点使用自己的Namespace对LocalCache进行逻辑分区.所以在LocalCache中进行读写採用的key为(namespa ...
- easyui datagrid种编辑器combobox选择的值不显示解决方案
var combobox_json = [{ "combobox_value" : "GDLB01", "combobox_name" : ...