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. 配置VS使用winteracter

    一.winteracter是什么?为什么要用VS代替wide?winteracter 是一款强大的 Fortran 图形界面函数库,可方便的用 Fortran 生成GUI界面,对话框,菜单,绘图等操作 ...

  2. javaweb学习第一天 debug

    debug 断点: f5:step into f6:step over f7:step return drop to frame:跳到当前方法的的第一行 resume:跳到下一个断点 watch:观察 ...

  3. HP XP7 GAD双活实现的理解

    XP7双活的虚拟卷global active device (GAD)实际上对应两个存储的两个物理卷(有点儿像Mirror Disk镜像) 当主机A向阵列A发出写数据请求后,阵列A首先检查要被写入的数 ...

  4. MFC CFileDialog用法例子。

     Set it to TRUE to construct a File Open dialog box. Set it to FALSE to construct a File Save As dia ...

  5. apache+tomcat分布式搭建

    windows 下Apache和tomcat整合 负载均衡session共享 准备工作: 1. Apache 2.2.4 下载地址:http://cztele1.skycn.com/down/apac ...

  6. mysql 更改自动增长字段值的重新设定

    今天在服务器上MYSQL库里的一个表插入数据,主键id是auto_increment自动增长类型的.发现插入的值从2247734开始,而实际上id的最大值才22722,不明原因. 删除了新增的,opt ...

  7. NOI 2001 食物链(eat)

    1074 食物链 2001年NOI全国竞赛  时间限制: 3 s  空间限制: 64000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description ...

  8. SVM3 Soft Margin SVM

    之前分为两部分讨论过SVM.第一部分讨论了线性SVM,并且针对线性不可分的数据,把原始的问题转化为对偶的SVM求解.http://www.cnblogs.com/futurehau/p/6143178 ...

  9. python学习笔记1-元类__metaclass__

    type 其实就是元类,type 是python 背后创建所有对象的元类   python 中的类的创建规则: 假设创建Foo 这个类 class Foo(Bar): def __init__(): ...

  10. getpid 与 gettid 与 pthread_self

    获取进程的PID(process ID) #include <unistd.h> pid_t getpid(void); 获取线程的TID(thread ID) 1)gettid或者类似g ...