hdu 1513 && 1159 poj Palindrome (dp, 滚动数组, LCS)
以前做过的一道题, 今天又加了一种方法 整理了一下。。。。。
题意:给出一个字符串,问要将这个字符串变成回文串要添加最少几个字符。
方法一:
将该字符串与其反转求一次LCS,然后所求就是n减去 最长公共子串的长度。
额,,这个思路还是不是很好想。
LCS:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = +;
char s1[maxn], s2[maxn];
int d[][maxn], n;
int mmin(int a,int b)
{
return a>b?b:a;
}
int mmax(int a, int b)
{
return a<b?b:a;
}
void Lcs()
{
int i, j;
for(i = ; i <= n; i++)
for(j = ; j <= n; j++)
if(s1[i] == s2[j])
d[i%][j] = d[(i-)%][j-] + ;
else
d[i%][j] = mmax(d[(i-)%][j], d[(i%)][j-]);
}
int main()
{
int i;
while(cin>>n)
{
memset(d, , sizeof(d));
for(i=; i<=n; i++)
cin>>s1[i];
for(i = n; i >=; i--)
s2[i] = s1[n-i+];
Lcs();
cout<<n-d[n%][n]<<endl;
}
return ;
}
方法二:
这个是discuss里的方法。
设ch[1]..ch[n]表示字符串1至n位,i为左游标,j为右游标 ,则i从n递减,j从i开始递增。
min[i][j]表示i和j之间至少需要插入多少个字符才能对称,初始置全0 ,我们最终需要得到的值是min[1][n].
则
if(ch[i]==ch[j]) //如果两个游标所指字符相同,向中间缩小范围
min[i][j]=min[i+1][j-1];
else
min[i][j] = 1 + (min[i+1][j]和min[i][j-1]中的较小值); //如果不同,典型的状态转换方程
下面这个代码 是用的short int d[5000][5000]
在poj 可以水过,但是在hdu还超内存,,所有需要用滚动数组来 节省内存。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; int mmin(int a,int b)
{
return a>b?b:a;
}
short int d[][];
int main()
{
int n,i,j;
char s[];
memset(d,,sizeof(d));
cin>>n;
for(i=; i<=n; i++)
cin>>s[i];
for(i=n; i>=; i--)
for(j=i+; j<=n; j++)
if(s[i]==s[j])
d[i][j]=d[i+][j-];
else
d[i][j]=mmin(d[i+][j],d[i][j-])+; cout<<d[][n]<<endl;
return ;
}
因为d[i][j] 算的时候只是与 d[i+1][j] 和 d[i][j+1]有关,所有可以开一个d[2][5000]的数组。
滚动数组节省内存:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; int mmin(int a,int b)
{
return a>b?b:a;
}
int d[][];
int main()
{
int n,i,j;
char s[];
while(cin>>n)
{
memset(d, , sizeof(d));
for(i=; i<=n; i++)
cin>>s[i]; for(i=n; i>=; i--)
for(j=i+; j<=n; j++)
if(s[i]==s[j])
d[i%][j]=d[(i+)%][j-];
else
d[i%][j]=mmin(d[(i+)%][j],d[i%][j-])+; cout<<d[][n]<<endl;
}
return ;
}
贴一下别人博客里的滚动数组的介绍:
滚动数组 举个简单的例子:
int i,d[100];
d[0]=1;d[1]=1;
for(i=2;i<100;i++)
d[i]=d[i-1]+d[i-2];
printf("%d",d[99]);
上面这个循环d[i]只需要解集中的前2个解d[i-1]和d[i-2];
为了节约空间用滚动数组的方法
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个解,数组好象在“滚动?一样,所以叫滚动数组
对于二维数组也可以用这种方法 例如:
int i,j,d[100][100];
for(i=1;i<100;i++)
for(j=0;j<100;j++)
d[i][j]=d[i-1][j]+d[i][j-1];
上?的d[i][j]忪便赖于d[i-1][j],d[i][j-1];
迿用滚动数组
int i,,j,d[2][100];
for(i=1;i<100;i++)
for(j=0;j<100;j++)
d[i%2][j]=d[(i-1)%2][j]+d[i%2][j-1];
滚动数组实际是一种节约空间的办法,时间上没什么优势,多用于DP中,举个例子先:
一个DP,平常如果需要1000×1000的空间,其实根据DP的特点,能以2×1000的空间解决问题,并且通过滚动,获得和1000×1000一样的效果。
hdu 1513 && 1159 poj Palindrome (dp, 滚动数组, LCS)的更多相关文章
- HDU 5617 Jam's maze dp+滚动数组
题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5617 bc(中文):http://bestcoder.hdu.edu.cn/contest ...
- HDU - 4576 Robot(概率dp+滚动数组)
题意:所有的格子围成一个圈,标号为1~n,若从格子1出发,每次指令告知行走的步数,但可能逆时针也可能顺时针走,概率都是1/2,那么问走了m次指令后位于格子l~r(1≤l≤r≤n)的概率. 分析: 1. ...
- hdu Max Sum Plus Plus(dp+滚动数组)
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 m为段,要深刻理解题意,并没有说是段与段要连接. 题解链接:http://blog.csdn.n ...
- HDU 1024 Max Sum Plus Plus --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- HDU 5119 Happy Matt Friends (背包DP + 滚动数组)
题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt ...
- POJ 3666 Making the Grade (DP滚动数组)
题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A[i],修理后是B[i],花费|A[i] – B[i]|,求最小花费.(数据有问题,代码只是单调递增的情况) #include <stdio ...
- USACO 2009 Open Grazing2 /// DP+滚动数组oj26223
题目大意: 输入n,s:n头牛 s个栅栏 输入n头牛的初始位置 改变他们的位置,满足 1.第一头与最后一头的距离尽量大 2.相邻两头牛之间的距离尽量满足 d=(s-1)/(n-1),偏差不超过1 3. ...
- poj - 1159 - Palindrome(滚动数组dp)
题意:一个长为N的字符串( 3 <= N <= 5000).问最少插入多少个字符使其变成回文串. 题目链接:http://poj.org/problem?id=1159 -->> ...
- hdu 1513(dp+滚动数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 思路:n这么大,可以采用滚动数组,然后就是求原串和反串的LCS了. #include<io ...
随机推荐
- 分布式文件系统 - FastDFS
分布式文件系统 - FastDFS 别问我在哪里 也许我早已不是我自己,别问我在哪里,我一直在这里. 突然不知道说些什么了... 初识 FastDFS 记得那是我刚毕业后进入的第一家公司,一个技术小白 ...
- C# File
http://msdn.microsoft.com/zh-cn/library/system.io.file(v=vs.110).aspx using System; using System.IO; ...
- unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor
eclipse启动项目时,提示超时: 解决方案: 修改 workspace\.metadata\.plugins\org.eclipse.wst.server.core\servers.xml文件. ...
- 1965: [Ahoi2005]SHUFFLE 洗牌 - BZOJ
Description 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小联 ...
- mac 搭建git服务器
一.简单搭建,不提供复杂的权限管理: 远程建立git用户,并打开ssh服务:见http://www.cnblogs.com/whj198579/archive/2013/04/09/3009350 ...
- HDU 3974 Assign the task 暴力/线段树
题目链接: 题目 Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- 基于AgileEAS.NET企业应用平台实现基于SOA架构的应用整合方案-开篇
开篇 系统架构的文章,准备在这段时间好好的梳理和整理一下,然后发布基于AgileEAS.NET平台之上的企业级应用架构实践,结合具体的案例来说明AgileEAS.NET平 台之上如何进行系统的逻辑架构 ...
- log4j 总结 精华
去年这个时候,为做软件工程的大作业就详细学过Log4J的用法了,时隔一年想要在新的项目中好好使用一下的时候,发现几乎全忘了,悲催啊…… 再上网查资料,总是不能找到一篇符合我的口味,拿来就能轻松上手,方 ...
- Eclipse下如何导入jar包
原地址:http://blog.csdn.net/justinavril/article/details/2783182 我们在用Eclipse开发程序的时候,经常想要用到第三方的jar包.这时候我们 ...
- 浏览器后退按钮导致jquery动态添加的select option值丢失的解决方法
监控浏览器返回功能 判断浏览器返回功能 禁用浏览器的后退按钮 JS禁止浏览器后退键 http://volunteer521.iteye.com/blog/830522/ 浏览器返回功能 判断上一页面来 ...