UVA 111 History Grading (最长公共子序列)

History Grading

Time Limit:3000MS     Memory Limit:0KB     64bit
IO Format:
%lld & %llu

Background

Many problems in Computer Science involve maximizing some measure according to constraints.

Consider a history exam in which students are asked to put several historical events into chronological order. Students who order all the events correctly will receive full credit, but how should partial credit be awarded to students who incorrectly rank one
or more of the historical events?

Some possibilities for partial credit include:

  1. 1 point for each event whose rank matches its correct rank
  2. 1 point for each event in the longest (not necessarily contiguous) sequence of events which are in the correct order relative to each other.

For example, if four events are correctly ordered 1 2 3 4 then the order 1 3 2 4 would receive a score of 2 using the first method (events 1 and 4 are correctly ranked) and a score of 3 using the second method (event sequences 1 2 4 and 1 3 4 are both in the
correct order relative to each other).

In this problem you are asked to write a program to score such questions using the second method.

The Problem

Given the correct chronological order of n events  as  where  denotes
the ranking of event i in the correct chronological order and a sequence of student responses  where  denotes
the chronological rank given by the student to event i; determine the length of the longest (not necessarily contiguous) sequence of events in the student responses that are in the correct chronological order relative to each other.

The Input

The first line of the input will consist of one integer n indicating the number of events with  . The
second line will contain nintegers, indicating the correct chronological order of n events. The remaining lines will each consist of n integers with each line representing a student‘s chronological ordering of the n events. All lines
will contain n numbers in the range  , with each number appearing exactly once per line, and with
each number separated from other numbers on the same line by one or more spaces.

The Output

For each student ranking of events your program should print the score for that ranking. There should be one line of output for each student ranking.

Sample Input 1

4
4 2 3 1
1 3 2 4
3 2 1 4
2 3 4 1

Sample Output 1

1
2
3

Sample Input 2

10
3 1 2 4 9 5 10 6 8 7
1 2 3 4 5 6 7 8 9 10
4 7 2 3 10 6 9 1 5 8
3 1 2 4 9 5 10 6 8 7
2 10 1 3 8 4 9 5 7 6

Sample Output 2

6
5
10
9

这道题,不用多说,最长公共子序列

刚开始,看到只用第二条规则求解以后,想到的就是公共子序列,然后就开始敲代码,把最长公共子序列的代码敲好,运行,测试,在 Sample Input1 中结果完全匹配的输出,提交, WA~~~~~~  ,甚是感觉郁闷,开始找错,看了几遍代码确定最长公共子序列写的有没错, 然后就测试 Sample
Input2 这组数据,结果连测试数据都没过,感觉更郁闷了,回来看第二条,没错啊,就是最长公共子序列啊,然后就有开始重新读题,看看是不是哪点理解错了,连蒙带猜的读了两遍题,还是没发现什么(英语不好是硬伤啊),再继续读,就这样又读了一会,又想了想,最后终于发现了,原来他给的顺序说的是第
i 个事件是在第几发生的,就像以前做的排序题那样,,,唉:-(    ,给跪了,都可以这样子,然后就改了改代码,提交,AC,(⊙o⊙)哦,真不 容易啊,一道最长公共子序列活生生的写了两个多小时~~~~~~~~~~~~~慢慢的都是泪啊~~~~~~~~~~~~~~!

题意大概就是说,给你 1 到 n 个事件,按照第一行的序列排序后与按照其他行序列排序后的最长公共子序列是多少。

附上代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#define INF 0x3f3f3f3f
#define MAX_N 100

using namespace std;

int num[MAX_N];
int dp[MAX_N][MAX_N];

int main()
{
	int n;
	cin >> n;
	for(int i = 1;i <= n;i++)
	{
		int k;
		cin >> k;
		num[k] = i;          //  按照给的顺序排列下
	}
	int a[MAX_N];
	int c;
	memset(dp,0,sizeof(dp));
	while(cin >> c)
	{
		a[c] = 1;
		for(int i = 2;i <= n;i++)
		{
			cin >> c;
			a[c] = i;             //   按照给的顺序排列下
		}
		for(int i = 1;i <= n;i++)        // dp求最长公共子序列
		{
			for(int j = 1;j <= n;j++)
			{
				if(num[i] == a[j])
				{
					dp[i + 1][j + 1] = dp[i][j] + 1;
				}
				else
				dp[i + 1][j + 1] = max(dp[i][j + 1],dp[i + 1][j]);
			}
		}
		cout << dp[n + 1][n + 1] << endl;
	}
	return 0;
}
时间: 2024-10-24 05:18:35

UVA 111 History Grading (最长公共子序列)的相关文章

uva 111 History Grading(DP初步应用)

uva 111 History Grading Many problems in Computer Science involve maximizing some measure according to constraints. Consider a history exam in which students are asked to put several historical events into chronological order. Students who order all

uva 10192 Vacation(最长公共子序列)

uva 10192 Vacation The Problem You are planning to take some rest and to go out on vacation, but you really don't know which cities you should visit. So, you ask your parents for help. Your mother says "My son, you MUST visit Paris, Madrid, Lisboa an

UVA 111 History Grading 【lcs】

Brief Description: 一个历史考试,有n个历史事件, 它们之间的年份是不同的,要学生把这些事件按照正确的顺序排列出来.有两种记分方式,采用的是第二种: 假设有历史事件1,2,3,4, 它们正确的时间顺序是1,2,3,4, 然后假设学生的答案是1,3,2,4, 那么按照相对顺序正确的数量,答对了三个(1,2,4或者1,3,4),也就是它与正确答案的最长公共子序列长度是3,便是答对的数量. Analyse: 最长公共子序列模板题,但是这题的输入是个很大的坑,他的输入是按照顺序,事件1

UVa 111 - History Grading

题目:历史上有一些事件发生的先后顺序,现在有很多学生写了不同的顺序表, 判断每个学生的最大的前后顺序正确的序列. 分析:dp,LIS,最大上升子序列. 注意本题的数据格式,串里的每个元素对应于:对应下标编号的事件在表中的位置: 状态:F(n)记录以第n个元素为结束元素的序列的最长上升子序列,有转移方程: F(n)= max(F(i)+1)  { 其中 0 < i < n 且 data[i] < data[n] }. 说明:发现好多dp题(⊙_⊙). #include <iostre

UVa 10192 Vacation (最长公共子序列)

Vacation Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Description   The Problem You are planning to take some rest and to go out on vacation, but you really don't know which cities you should visit. So, you ask your paren

uva 111 - History Grading (dp, LCS)

题目链接 题意:给N,第二行是答案,n个数c1---cn, 代表第一个的顺序是c1,第二个数顺序是c2; 下面每一行是学生的答案,格式同上. 注意:这个给的顺序需要处理一下,不能直接用. 思路:LCS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespac

UVA 10100- Longest Match(dp之最长公共子序列)

题目地址:UVA 10100 题意:求两组字符串中最大的按顺序出现的相同单词数目. 思路:将字串中的连续的字母认作一个单词,依次计算出两个字符串中的单词,其中第1个字符串的单词序列为t1.word[1]-..t1.word[n],第2个字符串的单词序列为t2.word[1]-..t2.word[m].然后将每个单词当成一个字符,使用LCS算法计算出两个字符串的最长公共子序列,该序列的长度就是最长匹配. #include <stdio.h> #include <math.h> #in

uva 10405 Longest Common Subsequence (最长公共子序列)

uva 10405 Longest Common Subsequence Sequence 1: Sequence 2: Given two sequences of characters, print the length of the longest common subsequence of both sequences. For example, the longest common subsequence of the following two sequences: abcdgh a

uva 10066 The Twin Towers (最长公共子序列)

uva 10066 The Twin Towers 题目大意:最长公共子序列. 解题思路:最长公共子序列. #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; int a[105], b[105], dp[105][105]; int main() { int n, m, Case = 1; while (scanf(