题意:给出一个长度为n的数字序列,代表了一些历史事件的发生顺序(时间顺序),然后给出一些学生对这些历史事件进行排序的答案,如果一个学生的答案内有一个长度为x的不连续的串同样符合答案的顺序可以加分,加的分数就是x的值,输出最大的x。

题解:是个最长公共子序列问题,输入很奇葩,比如是 4 2 3 1 ,意思是事件1发生在第4位,事件2发生在第2位,事件3发生在第3位, 事件4发生在第1位,所以要转化,a[i]保存历史事件i发生的顺序位置,b[i]保存学生的答案中历史事件i发生的顺序位置,然后套用模板做就很容易了。

#include <stdio.h>
#include <string.h>
const int N = 25;

int a[N], b[N], n, temp, f[N][N];

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &temp);
		a[temp] = i;
	}
	while (scanf("%d", &temp) != EOF) {
		b[temp] = 1;
		for (int i = 2; i <= n; i++) {
			scanf("%d", &temp);
			b[temp] = i;
		}
		memset(f, 0, sizeof(f));
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++)
				if (a[i] == b[j])
					f[i][j] = f[i - 1][j - 1] + 1;
				else
					f[i][j] = f[i][j - 1] >= f[i - 1][j] ? f[i][j - 1] : f[i - 1][j];
		}
		printf("%d\n", f[n][n]);
	}
	return 0;
}