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 ...
随机推荐
- VBS基础篇 - 常量
常量:指的是在程序运行过程中其值保持不变的量,它用来保存固定不变的数值,字符串等常数 . 常量的定义:在vbscript中使用使用 Const 指令可以创建名称具有一定含义的字符串型或数值型常量,并给 ...
- openstack安装、卸载与启动
一.安装: 更新: sudo apt-get update sudo apt-get upgrade 安装图形化界面: sudo apt-get install ubuntu-desktop 安装gc ...
- 对frameset、frame、iframe的js操作
框架编程概述一个HTML页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一个独立的HTML页面.这里所讲的框架编程包括框架的自我控制以及框架之间的互相访问,例如从一 ...
- 如何解决Mac与iPhone之间handoff连接问题
首先账户以及设备handoff开关问题不再赘述.主要是昨天发现的一个小技巧 当确认所有设备的iCloud账号统一.蓝牙打开.处在同一WiFi下的前提下,我的iPhone和Mac仍然handoff连接有 ...
- python 日期转星期
import time import datetime today = int(time.strftime('%w')) print today anyday = datetime.datetime( ...
- Eclipse中创建标准web工程以及标准目录结构说明
最近公司有个Web项目,项目结构如下: 虽然运行没有错,但是实在是别扭,标准的web应用一般不采用这种结构: 因此总结一下: 1.如何在Eclipse中创建一个标准的Web应用. 2. ...
- 【HDOJ】【4336】Card Collector
概率DP/数学期望/状压DP/容斥原理 kuangbin总结中的第14题 好神奇的做法……题解看kuangbin的代码好了…… //HDOJ 4336 #include<cstdio> # ...
- 【BZOJ】【1085】【SCOI2005】骑士精神
IDA*算法 Orz HZWER A*+迭代加深搜索=IDA* 这题的估价相当于一个可行性剪枝,即如果当前走的步数s+未归位的点数>搜索深度k,则剪枝 /******************** ...
- pureftpd安装配置-pureftp参数详解(一)
1. 下载 #cd /usr/local/src/ #wget ftp://ftp.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.30.tar.g ...
- asynDBcenter(复习)
asynDBCenter asynDBCenter是GS和DBCenter之间的模块,有了他GS访问数据库就是异步的了,以前是同步的,加入某个操作很耗时那么GS就在那等待这个返回值. .对于std:: ...