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>
using namespace std;

const int N = 25;
const int maxn = 10005;

int n;
int f[N];
int temp[N];
char str[maxn];

void translate (int * num) {

	memcpy (temp, num, n * sizeof (int));
	for (int i = 0; i < n; i++)
		num[temp[i] - 1] = i;
}

void handle (int * num) {

	int cnt = 0;
	int ans = 0;
	for (int i = 0; i <= strlen (str); i++) {

		if (str[i] >= '0' && str[i] <= '9') {

			ans = ans * 10 + str[i] - '0';
		} else {

			num[cnt++] = ans;
			ans = 0;
		}
	}

	translate (num);
}

int main () {

	int num[N];
	int vis[N];
	int num1[N];
	bool flag = 0;

	scanf ("%d%*c", &n);
	while (gets(str) != NULL) {

		if (!flag) {

			handle(num);
			flag = 1;
			for (int i = 0; i < n; i++)
				vis[num[i]] = i;
		} else {

			handle(num1);
			for (int i = 0; i < n; i++) {
				num1[i] = vis[num1[i]];
				f[i] = 1;
			}

			for (int i = 0; i < n; i++)
				for (int j = i - 1; j >= 0; j--) {

					if (num1[i] > num1[j])
						if (f[j] + 1 > f[i])
							f[i] = f[j] + 1;
				}

			int ans = 0;
			for (int i = 0; i < n; i++)
				if (ans < f[i])
					ans = f[i];
			printf ("%d\n", ans);
		}
	}
	return 0;
}
时间: 2024-08-01 20:19:56

UVA - 111History Grading(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 111-History Grading(DP/LCS)

题目链接:点击打开链接 题意坑.. 本来一看就是就裸LCS ,但题目中给的输入并不是原序列,而是原序列,而是原序列的位置..比如 3 1 2 并不是 s[1]=3 而是1在序列中位置是3 即 s[3]=1; (s[x]=i;) 然后输入处理一下就裸LCS. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string>

UVA 10534-Wavio Sequence(LIS)

题目大意:Wavio序列是关于整数的序列,有这样的性质: 1.长度为奇数,L=2*n+1 2.前n+1项严格递增 3.后n+1项严格递减 4.相邻的两个数不相等 给出n个数的序列,求出其中最长的Wavio子序列的长度. 依次对每个元素求以它为结束的最长上升子序列和以它为开始的最长下降子序列,b[i]为以i为最后一个元素的最长上升子序列,c[i]为以i为第一个元素的最长下降子序列,最后遍历每一个数,答案为max { min { b[i],c[i] } }. 代码是初学时写的,很难看..到时补个好的

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

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

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的一个子序列. 考虑最长公共子序列问题如何分解成