【bzoj2423】最长公共子序列[HAOI2010](dp)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2423
题目大意:求两个字符串的最长公共子序列长度和最长公共子序列个数。
这道题的话,对于神犇来说,肯定是一眼看出状态转移方程的。而我这个蒟蒻,看了几篇博客之后才看懂。。。
第一问模板lcs,大家肯定都会,就是设f[i][j]为A串跑到第i位,B串跑到第j为时的最长公共子序列长度,然后就有:
f[i][j]=f[i-1][j-1]+1 (a[i]==b[j])
=max(f[i-1][j],f[i][j-1]) (a[i]!=b[j]) (原谅我不会编辑公式)
我就解释一下第二问的方程。先设g[i][j]为A串跑到第i位,B串跑到第j为时的最长公共子序列个数,方程就是这样:
g[i][j]=g[i-1][j-1]
+g[i-1][j] (f[i][j]==f[i-1][j])
+g[i][j-1] (f[i][j]==f[i][j-1])
(a[i]==b[j])
=g[i-1][j] (f[i][j]==f[i-1][j])
+g[i][j-1] (f[i][j]==f[i][j-1])
-g[i-1][j-1] (f[i][j]==f[i-1][j-1])
(a[i]!=b[j])
这里当a[i]和b[j]相同时,g[i-1][j],g[i-1][j-1],g[i][j-1]这三个的最长公共子序列不会重复,因为这里的g[i-1][j-1]实际上还要在末尾添加上a[i](或b[j]),因此这些lcs全都是以a[i],b[j]结尾的,而g[i-1][j]不包含以a[i]结尾的lcs,g[i][j-1]不包含以b[j]结尾的lcs,因此这三类lcs不会重复,可以直接相加。
当a[i]与b[j]不同时,最后当f[i][j]==f[i-1][j-1]时要减去g[i-1][j-1]就是因为这时g[i-1][j-1]被分别包含在g[i-1][j]和g[i][j-1]中,算了两次,要把重复的减掉。
于是就可以愉快地AC这道题了。
还有,一定要用滚动数组,不然爆!空!间!
丑代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int mod=;
int f[][],g[][];
char a[],b[];
int main()
{
int i,j,n,m;
scanf("%s%s",a,b);
n=strlen(a)-; m=strlen(b)-;
for(i=;i<=m;i++)g[][i]=; g[][]=;
for(i=;i<=n;i++)
for(j=;j<=m;j++)
if(a[i-]==b[j-]){
f[i&][j]=f[i&^][j-]+;
g[i&][j]=(g[i&^][j-]+(f[i&^][j]==f[i&][j])*g[i&^][j]+(f[i&][j-]==f[i&][j])*g[i&][j-])%mod;
}
else{
if(f[i&^][j]>f[i&][j-])f[i&][j]=f[i&^][j];else f[i&][j]=f[i&][j-];
g[i&][j]=((f[i&^][j]==f[i&][j])*g[i&^][j]+(f[i&][j-]==f[i&][j])*g[i&][j-]-(f[i&][j]==f[i&^][j-])*g[i&^][j-]+mod)%mod;
}
printf("%d\n%d",f[n&][m],g[n&][m]);
}
【bzoj2423】最长公共子序列[HAOI2010](dp)的更多相关文章
- bzoj 2423: [HAOI2010]最长公共子序列【dp+计数】
设f[i][j]为a序列前i个字符和b序列前j个字符的最长公共子序列,转移很好说就是f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+(a[i]==b[j])) ...
- poj1458 求最长公共子序列 经典DP
Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 45763 Accepted: 18 ...
- P1439 【模板】最长公共子序列(DP)
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...
- hdu 1159 Common Subsequence(最长公共子序列,DP)
题意: 两个字符串,判断最长公共子序列的长度. 思路: 直接看代码,,注意边界处理 代码: char s1[505], s2[505]; int dp[505][505]; int main(){ w ...
- 洛谷 P1439 【模板】最长公共子序列(DP,LIS?)
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...
- 最长公共子序列(DP)
Description 一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列 X = { x1,x2,…,xm },则另一序列Z ={ z1,z2,…,zk },X 的子序列 ...
- NYOJ 36 最长公共子序列 (还是dp)
这个好多算法书上都有,不仅限于<算法导论> 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描写叙述 咱们就不拐弯抹角了,如题.须要你做的就是写一个程序,得出最长公 ...
- PKU 1458 Common Subsequence(最长公共子序列,dp,简单)
题目 同:ZJU 1733,HDU 1159 #include <stdio.h> #include <string.h> #include <algorithm> ...
- 【noi 2.6_1808】最长公共子序列(DP)
题意:给2个字符串求其最大公共子序列的长度.解法:这个和一般的状态定义有点不一样,f[i][j]表示 str 前i位和 str2 前j的最大公共子序列的长度,而不是选 str 的第i位和 str2 的 ...
随机推荐
- TypeError: write() argument must be str, not bytes
w文件打开以 '二进制' 方式: with open('teacher.html','wb+') as f: f.write(response.body) 要写入"中文",防止乱 ...
- redis 集群出现的错误
1 解决方法: 不用 Jedis jed =new jedis("192.168.56.101"); jed.set(key,value); 用 Set<HostAndPor ...
- 错误命令“if not exist "\Dll" mkdir "\Dll" xcopy "\bin\Debug\*.*" "F:\647\VS项目\EtrolMes2014SY\Framework\Dll" /e /i /y”已退出,代码为 9009
分析错误 第一步:观察错误,发现plugin文件夹中未生成对应的编译文件. 第二步:XCOPY命令无法执行,百度xcopy为何无法执行 第三步,搜索,发现环境变量未配置正确. 就是环境变量path(大 ...
- ubuntu虚拟化平台libvrit-bin
http://download.cirros-cloud.net/0.3.5/ 下载 cirros-0.3.5-x86_64-disk.img 因为 KVM(准确说是 Libvirt)默认不接受远程管 ...
- IOS学习笔记(五)——UI基础UIWindow、UIView
在PC中,应用程序多是使用视窗的形式显示内容,手机应用也不例外,手机应用中要在屏幕上显示内容首先要创建一个窗口承载内容,iOS应用中使用UIWindow.UIView来实现内容显示. UIWindow ...
- [Spring Data MongoDB]学习笔记--建立数据库的连接
1. 有了上一篇的Mongo后,连接数据库我们还需要更多的信息,比如数据库名字,用户名和密码等. 我们可以继续来配置MongoDbFactory的实例. public interface MongoD ...
- csu1326(The contest)
题目链接:传送门 题目思路:并查集加分组背包 #include <iostream> #include <cstdio> #include <cstdlib> #i ...
- 【BZOJ2242】[SDOI2011]计算器 BSGS
[BZOJ2242][SDOI2011]计算器 Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ ...
- MongoDB实践-自定义ASP.NET Session Store
Session由来 由于HTTP协议是无状态的,客户端与服务器端进行“请求-响应”操作后,建立的连接就释放了,服务器端根本不知道刚才是哪个客户端访问的.但是有些场景是需要知道客户端的状态的,最典型的就 ...
- 不恰当使用线程池处理 MQ 消息引起的故障
现状 业务部门反应网站访问特别慢,负责运维监控的同事说MQ消息队列积压了,中间件的说应用服务器内存占用很高,GC 一直回收不了内存,GC 线程占了近 100% 的 CPU,其他的基本上都在等待,数据库 ...