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;
}

uva10723 - Cyborg Genes(LIS),布布扣,bubuko.com

时间: 2024-10-20 03:03:41

uva10723 - Cyborg Genes(LIS)的相关文章

10723 - Cyborg Genes(LCS)

该题实际上就是LCS的变形,所要求的最短合成串长度其实就是两串相加再减去LCS的长度 .  很好理解,因为合成串中一定要包含LCS中的元素,然后非LCS的元素都要加进去,这样两串相加就多了一个LCS . 所以答案就是len1 + len2 - len_LCS 然而该题的难点是求最优解的个数 . 显然,由于合成串中一定要有LCS,因此,解的个数的求解和刚才完成的dp有着千丝万缕的联系 .  那么我们不妨利用刚才的dp路径 ,或者说直接在那个dp中进行 . 边界条件是 1 ,设i.j为当前判断的字符

UVA-10273 Cyborg Genes (DP)

题目大意:给两个字符串a.b,找出一个最短的字符串c,使得这两个字符串都是c的子序列.只需找出p的最小长度和最小长度时的个数. 题目分析:与LCS问题类似.最小长度的状态转移方程,dp(i,j)=min(dp(i-1,j)+1,dp(i,j-1)+1,dp(i-1,j-1)+(a[i]==b[j])?1:2):个数也是差不多的求法,求所有最优决策对应的子问题的答案之和便是当前状态的答案总个数. 这是一道SB题,输入的字符串可能含有空格,用scanf读入字符串会WA.WA.WA!!!!! 代码如下

UVA - 10723 Cyborg Genes (LCS)

题目: 思路: 求两个串的最长公共子序列,则这个最短的串就是给出的两个串的长度和减去最长公共子序列的长度. 状态转移方程: 如果s[i-1]==t[j-1]就有dp[i][j] = dp[i-1][j-1]+1; 否则有dp[i][j] = max(dp[i-1][j], dp[i][j-1]) dp[i][j]表示从s中选前i个,从t中选前j个字符中最长公共子序列的长度. 注意: 给出的两个串可能是空串,这时候就要用gets来输入字符串. 代码: #include <bits/stdc++.h

Gym 101246H ``North-East&#39;&#39;(LIS)

http://codeforces.com/gym/101246/problem/H 题意: 给出n个点的坐标,现在有一个乐队,他可以从任一点出发,但是只能往右上方走(包括右方和上方),要经过尽量多的点.输出它可能经过的点和一定会经过的点. 思路: 分析一下第一个案例,在坐标图上画出来,可以发现,他最多可以经过4个点,有两种方法可以走. 观察一下,就可以发现这道题目就是要我们求一个LIS. 首先,对输入数据排一下顺序,x小的排前,相等时则将y大的优先排前面. 用二分法求LIS,这样在d数组中就可

UVA - 10534Wavio Sequence(LIS)

题目:UVA - 10534Wavio Sequence(LIS) 题目大意:给出N个数字,找出这样的序列:2 * n + 1个数字组成.前面的n + 1个数字单调递增,后面n + 1单调递减. 解题思路:从前往后找一遍LIS,再从后往前找一遍LIS.最后只要i这个位置的LIS的长度和LDS的长度取最小值.再*2 - 1就是这个波浪数字的长度.注意这里的求LIS要用nlog(n)的算法,而且这里的波浪数字的对称并不是要求i的LIS == LDS,而是只要求LIS和LDS最短的长度就行了,长的那个

hoj_10001_朴素DP(LIS)

Longest Ordered Subsequence Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB Total submit users: 1937, Accepted users: 1621 Problem 10001 : No special judgement Problem description A numeric sequence of ai is ordered if a1 < a2 <

最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)

最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj.例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列. 考虑最长公共子序列问题如何分解成

poj 3903 &amp; poj 2533 最长上升子序列(LIS)

最长上升子序列. 做这道题之前先做了2533,再看这道题,感觉两道题就一模一样,于是用2533的代码直接交, TLE了: 回头一看,数据范围.2533 N:0~1000:3903 N :1~100000. 原因终归于算法时间复杂度. 也借这道题学习了nlgn的最长上升子序列.(学习链接:http://blog.csdn.net/dangwenliang/article/details/5728363) 下面简单介绍n^2 和 nlgn 的两种算法. n^2: 主要思想:DP: 假设A1,A2..

BZOJ 1049 数字序列(LIS)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1049 题意:给出一个数列A,要求:(1)修改最少的数字使得数列严格递增:(2)在(1)的基础上使得修改的绝对值之和最小. 思路:对于第一问看起来像是求最长上升子 列,其实不是.我们想,若对于i<j,j能由i转移过来,那么需满足A[j]-A[i]>=j-i才行,这样我们发现只要A[j]-j& gt;=A[i]-i即可.因此令A[i]=A[i]-i,这样求LIS即可.对于第二问,