Yes, you are developing a 'Love calculator'. The software would be quite complex such that nobody could crack the exact behavior of the software.

So, given two names your software will generate the percentage of their 'love' according to their names. The software requires the following things:

1.                  The length of the shortest string that contains the names as subsequence.

2.                   Total number of unique shortest strings which contain the names as subsequence.

Now your task is to find these parts.

Input

Input starts with an integer T (≤ 125), denoting the number of test cases.

Each of the test cases consists of two lines each containing a name. The names will contain no more than 30 capital letters.

Output

For each of the test cases, you need to print one line of output. The output for each test case starts with the test case number, followed by the shortest length of the string and the number of unique strings that satisfies the given conditions.

You can assume that the number of unique strings will always be less than 263. Look at the sample output for the exact format.

Sample Input

Output for Sample Input

3

USA

USSR

LAILI

MAJNU

SHAHJAHAN

MOMTAJ

Case 1: 5 3

Case 2: 9 40

Case 3: 13 15

题目大意:
给你两个串, 让你求出这两个串能组成的最短串的长度,以及最短串多少种不同的串(第三个串中保证有最长公共字串)
 
最长公共子序列, 在求最长公共子序列的过程中加上每个串有多少种组成方法
 
dp[i][j] 代表第一个串的前i个和第二个串的前j个的最长公共子序列
num[i][j]代表第一个串的前i个和第二个串的钱j个能组成多少种不同的串
 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm> using namespace std; #define N 1100 #define met(a,b) (memset(a,b,sizeof(a)))
typedef long long LL; int a[][], dp[][];
LL num[][]; int main()
{
int T, iCase=; scanf("%d", &T); while(T--)
{
char s1[], s2[];
int i, j, len1, len2; met(dp, );
met(num, );
scanf("%s%s", s1, s2);
len1 = strlen(s1);
len2 = strlen(s2); for(i=; i<=len1; i++)
num[i][] = ;
for(i=; i<=len2; i++)
num[][i] = ; for(i=; i<=len1; i++)
for(j=; j<=len2; j++)
{
if(s1[i-]==s2[j-])
{
dp[i][j] = dp[i-][j-] + ;
num[i][j] += num[i-][j-];
}
else
{
if(dp[i-][j]>dp[i][j-])
{
dp[i][j] = dp[i-][j];
num[i][j] = num[i-][j];
}
else if(dp[i-][j]<dp[i][j-])
{
dp[i][j] = dp[i][j-];
num[i][j] = num[i][j-];
}
else
{
dp[i][j] = dp[i-][j];
num[i][j] = num[i-][j] + num[i][j-];
}
}
} printf("Case %d: %d %lld\n", iCase++, len1+len2-dp[len1][len2], num[len1][len2]);
}
return ;
} /**
3
USA
USSR
LAILI
MAJNU
SHAHJAHAN
MOMTAJ
*/

自己写完后, 搜题解看到的另一种写法, 由于dp刚入门, 就学习一下思想

dp[C串的长度][包含A的字符个数][包含B的字符个数] = 种类数

状态转移:如果 A[i] == B[j] 那么 dp[k][i][j] = dp[k-1][i-1][j-1]. 就是说我最后一个字符是相同的那么我只要放一个就可以了。

     如果 A[i] !=  B[j] 那么 dp[k][i][j] = dp[k-1][i-1][j] + dp[k-1][i][j-1].最后一个字符我们要么放A[i] 要么放 B[j] 就这两种情况了。

然后关于找最短的,就可以在 dp[k][lenA][lenB] 种找到最小的k即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm> using namespace std; #define N 1100 #define met(a,b) (memset(a,b,sizeof(a)))
typedef long long LL; LL dp[][][]; int main()
{
int T, iCase=; scanf("%d", &T); while(T--)
{
char s1[], s2[];
int i, j, k, len1, len2; met(dp, );
scanf("%s%s", s1, s2);
len1 = strlen(s1);
len2 = strlen(s2); for(i=; i<=len1; i++)
dp[i][i][] = ;
for(i=; i<=len2; i++)
dp[i][][i] = ; for(i=; i<=len1+len2; i++)
{
for(j=; j<=len1; j++)
for(k=; k<=len2; k++)
{
if(s1[j-]==s2[k-])
dp[i][j][k] = dp[i-][j-][k-];
else
dp[i][j][k] = dp[i-][j-][k] + dp[i-][j][k-];
}
} for(k=; k<=len1+len2; k++)
if(dp[k][len1][len2]) break; printf("Case %d: %d %lld\n", iCase++, k, dp[k][len1][len2]);
}
return ;
} /**
3
USA
USSR
LAILI
MAJNU
SHAHJAHAN
MOMTAJ
*/

(最长公共子序列+推导)Love Calculator (lightOJ 1013)的更多相关文章

  1. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  2. 最长公共子序列与最长公共字串 (dp)转载http://blog.csdn.net/u012102306/article/details/53184446

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  3. 算法练习——最长公共子序列的问题(LCS)

    问题描述: 对于两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列.X  Y   各自字符串有顺序,但是不一定需要相邻. 最长公共子串(Longest Common Subst ...

  4. DP_最长公共子序列/动规入门

    学自:https://open.163.com/movie/2010/12/L/4/M6UTT5U0I_M6V2U1HL4.html 最长公共子序列:(本文先谈如何求出最长公共子序列的长度,求出最长公 ...

  5. 题解报告:hdu 1159 Common Subsequence(最长公共子序列LCS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Problem Description 给定序列的子序列是给定的序列,其中有一些元素(可能没有) ...

  6. DP的初级问题——01包、最长公共子序列、完全背包、01包value、多重部分和、最长上升子序列、划分数问题、多重集组合数

    当初学者最开始学习 dp 的时候往往接触的是一大堆的 背包 dp 问题, 那么我们在这里就不妨讨论一下常见的几种背包的 dp 问题: 初级的时候背包 dp 就完全相当于BFS DFS 进行搜索之后的记 ...

  7. 【转】动态规划之最长公共子序列(LCS)

    [原文链接]最长公共子序列(Longest Common Subsequence,简称 LCS)是一道非常经典的面试题目,因为它的解法是典型的二维动态规划,大部分比较困难的字符串问题都和这个问题一个套 ...

  8. 【转】最长公共子序列(LCS),求LCS长度和打印输出LCS

    求LCS的长度,Java版本: public static int LCS(int[]a,int[] b) { int [][]c=new int[a.length+1][b.length+1]; f ...

  9. 用python实现最长公共子序列算法(找到所有最长公共子串)

    软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...

随机推荐

  1. c语言 sscanf()函数

    sscanf()函数用于从字符串中读取指定格式的数据,其原型如下:    int sscanf (char *str, char * format [, argument, ...]); [参数]参数 ...

  2. Kettle6使用

    1.Kettle是一个开源的ETL(Extract-Transform-Load的缩写,即数据抽取.转换.装载的过程)项目,java编写,绿色无需安装 下载http://community.penta ...

  3. Oracle 查询系统所有用户信息

    1.查看所有用户:select * from dba_users;   select * from all_users;   select * from user_users; 2.查看用户或角色系统 ...

  4. 【转】详解Oracle的dual表

    网址:http://www.adp-gmbh.ch/ora/misc/dual.html dual is a table which is created by oracle along with t ...

  5. JavaScript Function(函数表达式)

    创建函数 创建函数的方式有两种:1.函数声明,2.函数表达式 函数声明的语法为 functionName(); //不会报错,函数声明提升function functionName(arg0,arg1 ...

  6. Hadoop HDFS编程 API入门系列之合并小文件到HDFS(三)

    不多说,直接上代码.  代码 package zhouls.bigdata.myWholeHadoop.HDFS.hdfs7; import java.io.IOException;import ja ...

  7. Scala class的构造方法与继承

    有java背景的人,很清楚java是如何定义构造方法以及继承的.在scala里面,继承和java有些相似.但是构造方法的定义,就不大一样了,应该说是差别还是很大的.在java里面,定义构造方法,就是定 ...

  8. 处理返回结果(XML)

    var xmlHttp function showUser(str) { xmlHttp=GetXmlHttpObject() if (xmlHttp==null) { alert ("Br ...

  9. java基础八 [序列化和文件的输入/输出](阅读Head First Java记录)

    对象具有状态和行为两种属性.行为存在类中的方法中,想要保存状态有多种方法,这里介绍两种: 一是保存整个当前对象本身(通过序列化):一是将对象中各个状态值保存到文件中(这种方式可以给其他非JAVA程序用 ...

  10. poj 2060 Taxi Cab Scheme (二分匹配)

    Taxi Cab Scheme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5710   Accepted: 2393 D ...