首页 > 代码库 > uva10723 - Cyborg Genes(LIS)
uva10723 - Cyborg Genes(LIS)
题目:uva10723 - Cyborg Genes(LIS)
题目大意:给出两个字符串,要求的到一个新的字符串,它保持了两个字符串的字符的特征,也就是可以在这个字符串中找到前两个字符串的子序列,求这样的字符串的最短长度和有多少种这样的不同的字符串。
解题思路:LIS。首先先要找出最长的公共子序列,这样得到的新的字符串的长度才会是最小:l1 + l2 - l【1】【N】;
l[i][j] :第一个字符串的前i个字符和第二个字符串的前j个字符的最长的公共子序列长度。
n[i][j]: 使得第一个字符串的前i个字符和第二个字符串的前j个字符形成最短的不同的新的字符串的数目。
s[i] == s[j] , l[i][j] = l[ i- 1][j - 1] + 1; n[i][j] = n[i- 1][j - 1] ;
s[i] != s[j] , l[i][j] = Max (l[i-1][j], l[i][j - 1]); if (l[i - 1][j] > l[i][ j- 1]) n[i][j] = n[i - 1][j];(因为是要最短的字符串的种类)反之则反之。相等的情况:n[i][j] = n[i-1][j] + n[i][j - 1];
初始化:l【i】【0】 = l【0】【j】 = 0; n【0】【j】 = n【i】【0】 = 1;
代码:
#include <cstdio> #include <cstring> const int N = 35; typedef long long ll; int l[N][N]; ll n[N][N]; char s1[N], s2[N]; int l1, l2; int Max (const int a, const int b) { return a > b? a: b; } void init () { l1 = strlen (s1); l2 = strlen (s2); memset (l, 0, sizeof (l)); for (int i = 0; i <= l1; i++) n[i][0] = 1; for (int i = 0; i <= l2; i++) n[0][i] = 1; } int main () { int t; scanf ("%d%*c", &t); for (int k = 1; k <= t; k++) { printf ("Case #%d:", k); gets (s1); gets (s2); init (); for (int i = 1; i <= l1; i++) { for (int j = 1; j <= l2; j++) { if (s1[i - 1] == s2[j - 1]) { l[i][j] = l[i - 1][j - 1] + 1; n[i][j] = n[i - 1][j - 1]; } else { l[i][j] = Max (l[i - 1][j], l[i][j - 1]); // printf ("%d %d %d %d %d\n", i, j, l[i - 1][j], l[i][j - 1], l[i][j]); if (l[i - 1][j] > l[i][j - 1]) n[i][j] = n[i - 1][j]; else if (l[i - 1][j] < l[i][j - 1]) n[i][j] = n[i][j - 1]; else n[i][j] = n[i][j - 1] + n[i - 1][j]; } } } printf (" %d %lld\n", l1 + l2 - l[l1][l2], n[l1][l2]); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。