UVA - 531Compromise(LIS)

题目:UVA - 531Compromise(LIS)

题目大意:给出两段话,找出里面最长的公共单词的子序列。并且输出任意一个子序列。

解题思路:LIS。

代码:

#include <cstdio>
#include <cstring>

const int N = 105;
const int M = 35;

char w1[N][M];
char w2[N][M];

int f[N][N];
int p[N][N][2];
int ans[N];
int n1, n2;

void printf_ans (int x, int y) {

	if (x == 0 || y == 0)
		return;
	printf_ans (p[x][y][0], p[x][y][1]);
	if (strcmp (w1[x - 1], w2[y - 1]) == 0)
		ans[f[x][y]] = x - 1;
}

int main () {

	n1 = n2 = 0;
	while (scanf ("%s", w1[n1++]) != EOF) {

		while (scanf ("%s", w1[n1]) && w1[n1][0] != '#') {
			n1++;
		}
		while (scanf ("%s", w2[n2]) && w2[n2][0] != '#') {
			n2++;
		}

		for (int i = 0; i <= n1; i++)
			f[i][0] = 0;
		for (int i = 0; i <= n2; i++)
			f[0][i] = 0;

		for (int i = 1; i <= n1; i++)
			for (int j = 1; j <= n2; j++) {

				if (strcmp(w1[i - 1], w2[j - 1]) == 0)  {

					f[i][j] = f[i - 1][j - 1] + 1;
					p[i][j][0]  = i - 1;
					p[i][j][1]  = j - 1;
				} else { 

					if (f[i][j - 1] > f[i - 1][j]) {
						f[i][j] = f[i][j -1];
						p[i][j][0] = i;
						p[i][j][1] = j - 1;
					} else {

						f[i][j] = f[i - 1][j];
						p[i][j][0] = i - 1;
						p[i][j][1] = j;
					}
				}
			}

		printf_ans(n1, n2);
		for (int i = 1; i < f[n1][n2]; i++)
			printf ("%s ", w1[ans[i]]);
		printf ("%s\n", w1[ans[f[n1][n2]]]);
		n1 = n2 = 0;
	}

}
时间: 2024-10-07 09:37:29

UVA - 531Compromise(LIS)的相关文章

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最短的长度就行了,长的那个

UVA - 10066The Twin Towers(LIS)

题目:UVA - 10066The Twin Towers(LIS) 题目大意:求两个整数序列的最长公共子序列. 解题思路:和uva10405同样的思路.注意每组输出后面要输出空行,不然会WA. 代码: #include <cstdio> #include <cstring> const int N = 105; int s1[N], s2[N]; int l[N][N]; int l1, l2; void init () { memset (l, 0, sizeof (l));

UVA - 111History Grading(LIS)

题目:UVA - 111History Grading(LIS) 题目大意:找最长的LIS.但是题意讲的实在是有问题. 例如:3 1 2 4 9 5 10 6 8 7,意思是第一个历史事件的时间是排在第三位,第二个历史事件是在第1位,那么首先先要将这个事件按照时间顺序重新排序.新的排列顺序:2 3 1 4 6 8 10 9 5 7. 解题思路:LIS. 代码: #include <cstdio> #include <cstring> #include <algorithm&g

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

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

uva10723 - Cyborg Genes(LIS)

题目:uva10723 - Cyborg Genes(LIS) 题目大意:给出两个字符串,要求的到一个新的字符串,它保持了两个字符串的字符的特征,也就是可以在这个字符串中找到前两个字符串的子序列,求这样的字符串的最短长度和有多少种这样的不同的字符串. 解题思路:LIS.首先先要找出最长的公共子序列,这样得到的新的字符串的长度才会是最小:l1 + l2 - l[1][N]: l[i][j] :第一个字符串的前i个字符和第二个字符串的前j个字符的最长的公共子序列长度. n[i][j]: 使得第一个字

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即可.对于第二问,