LCS的数量

题意:

给出两个字符串,A,B,求A,B的lcs的数量。

题解:

在LCS的时候同时计算方案QAQ,可是傻逼的我不会,不会,不会。。。。。。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int mod = 1e9 + 7;
const int N = 1e3 + 7;
int dp[N][N], sum[N][N];
char ch1[N], ch2[N];

int main () {
	scanf ("%s%s", ch1 + 1, ch2 + 1);
	int n = strlen (ch1 + 1);
	int m = strlen (ch2 + 1);
	for (int i = 0; i <= n; ++i) sum[i][0] = 1;
	for (int j = 0; j <= m; j++) sum[0][j] = 1;

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			if (dp[i][j] < dp[i - 1][j]) {
				dp[i][j] = dp[i - 1][j];
				sum[i][j] = sum[i - 1][j];
			}
			else if (dp[i][j] == dp[i - 1][j]) {
				sum[i][j] = (sum[i][j] + sum[i - 1][j]) % mod;
			}
			if (dp[i][j] < dp[i][j - 1]) {
				dp[i][j] = dp[i][j - 1];
				sum[i][j] = sum[i][j - 1];
			}
			else if (dp[i][j] == dp[i][j - 1]) {
				sum[i][j] = (sum[i][j] + sum[i][j - 1]) % mod;
			}
			if (ch1[i] == ch2[j]) {
				if (dp[i][j] < dp[i - 1][j - 1] + 1) {
					dp[i][j] = dp[i - 1][j - 1] + 1;
					sum[i][j] = sum[i - 1][j - 1];
				}
				else if (dp[i][j] == dp[i - 1][j - 1] + 1) {
					sum[i][j] = (sum[i][j] + sum[i - 1][j - 1]) % mod;
				}
			}
		}
	}
	printf("%d\n", sum[n][m]);
	return 0;
}

  

总结:

一个基础的DP,我竟然不会QAQ,我真为“志几”感到捉急...

时间: 2025-01-14 11:53:03

LCS的数量的相关文章

poj 1159 Palindrome (LCS)

链接:poj 1159 题意:给定一个字符串,求最少添加多少个字符可使得该字符串变为回文字符串 分析:设原序列S的逆序列为S' ,最少需要补充的字母数 = 原序列S的长度 - S和S'的最长公共子串长度 原因:要求最少添加几个字符,我们可以先从原串中找到一个最长回文串,然后对于原串中不属于这个回文串的字符,在它关于回文串中心的对称位置添加一个相同字符即可.那么需要添加的字符数量即为n-最长回文串长度. 最长回文串可以看作是原串中前面和后面字符的一种匹配(每个后面的字符在前面找到一个符合位置要求的

CSU 1446 Modified LCS 扩展欧几里得

要死了,这个题竟然做了两天……各种奇葩的错误…… HNU的12831也是这个题. 题意: 给你两个等差数列,求这两个数列的公共元素的数量. 每个数列按照以下格式给出: N F D(分别表示每个数列的长度,首项,公差). 思路: 先用扩展欧几里得得到两个数列的一个交点,然后求出两个数列的第一个交点.然后分别得到从第一个交点,到末项的可能交点数量. 假设 F1+K1*D1 = F2+K2*D2 是某一个交点, 移向得到 F1 - F2 = K2*D2 - K1*D1. 由扩展欧几里得定理的结论 x*

51Nod - 1092 回文字符串(添加删除字符LCS变形)

回文字符串 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串.每个字符串都可以通过向中间添加一些字符,使之变为回文字符串. 例如:abbc 添加2个字符可以变为 acbbca,也可以添加3个变为 abbcbba.方案1只需要添加2个字符,是所有方案中添加字符数量最少的. Input输入一个字符串Str,Str的长度 <= 1000.Output输出最少添加多少个字符可以使之变为回文字串.Sample Input abbc Sample Output 2 向字符串中间添加(

[数学]JZOJ 4673 LCS again

Description 现在有一个长度为n的串S,其中每一个字母都是前m个小写字母计算有多少个不同的长度为n的T(其中T也是由前m个小写字母组成),并且S与T的LCS为n-1LCS就是同时存在于S和T的最长子序列 Input 第一行包含两个整数n和m表示S的长度和前m个小写字母第二行是串S Output 只要输出存在的T的数量 Sample Input 输入1:3 3aaa 输入2:3 3aab 输入3:1 2a 输入4:10 9abacadefgh Sample Output 输出1:6 输出

C#:多进程开发,控制进程数量

正在c#程序优化时,如果多线程效果不佳的情况下,也会使用多进程的方案,如下: System.Threading.Tasks.Task task=System.Threading.Tasks.Task.Factory.StartNew( (object mystate) => { Process process = Process.Start("AutoCollectMrMultipleProcess.exe", mystate.ToString()); process.WaitF

HDU 1513 Palindrome:LCS(最长公共子序列)or 记忆化搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 题意: 给你一个字符串s,你可以在s中的任意位置添加任意字符,问你将s变成一个回文串最少需要添加字符的个数. 题解1(LCS): 很神奇的做法. 先求s和s的反串的LCS,也就是原串中已经满足回文性质的字符个数. 然后要变成回文串的话,只需要为剩下的每个落单的字符,相应地插入一个和它相同的字符即可. 所以答案是:s.size()-LCS(s,rev(s)) 另外,求LCS时只会用到lcs[i-

1003 阶乘后面0的数量

1003 阶乘后面0的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 n的阶乘后面有多少个0? 6的阶乘 = 1*2*3*4*5*6 = 720,720后面有1个0. Input 一个数N(1 <= N <= 10^9) Output 输出0的数量 Input示例 5 Output示例 1其实只要循环除五就可以找到规律,其实也可以证明出来. 1 #include <iostream> 2 #include <cstdio> 3 #

CodeVS 1359 数字计数 51nod 1042 数字0-9的数量 Pascal

题目大意: 我的代码又臭又长,但是毕竟是我这个jr想了几天才推出的公式,看别的大神都写数位DP,所以我决定分享一下我的思路.我认为我的思路一向是最好理解的! 要分两种情况讨论: 1.0的情况.我们首先推出0~9中只有1个0,在0~99中有(1+(9*100*1))个0{第一位可以为1~9,第二位可以为0~9,0只可以放在后者,所以乘1},在0~999中有((1+(9*100*1))+(9*101*2))个0~6666为例,先算出0~999中0的个数,在算出1000~5999中0的个数,则为(10

大并发大数量中的MYSQL瓶颈与NOSQL介绍

NoSQL在2010年风生水起,大大小小的Web站点在追求高性能高可靠性方面,不由自主都选择了NoSQL技术作为优先考虑的方面.今年伊始,InfoQ中文站有幸邀请到凤凰网的孙立先生,为大家分享他之于NoSQL方面的经验和体会. 非 常荣幸能受邀在InfoQ开辟这样一个关于NoSQL的专栏,InfoQ是我非常尊重的一家技术媒体,同时我也希望借助InfoQ,在国内推动NoSQL 的发展,希望跟我一样有兴趣的朋友加入进来.这次的NoSQL专栏系列将先整体介绍NoSQL,然后介绍如何把NoSQL运用到自