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

来源:互联网 发布:怎样学c语言 编辑:程序博客网 时间:2024/05/22 19:51
题意:
一个历史考试,有n个历史事件, 它们之间的年份是不同的,要学生把这些事件按照正确的顺序排列出来。
有两种记分方式,采用的是第二种: 假设有历史事件1,2,3,4, 它们正确的时间顺序是1,2,3,4, 然后假设学生的答案是1,3,2,4, 那么按照相对顺序正确的数量,答对了三个(1,2,4或者1,3,4),也就是它与正确答案的最长公共子序列长度是3,便是答对的数量。
请你求出答对的数量。

解析:最长公共子序列的模板题,但是请注意先要将序列进行转换。
原序列是按时间顺序的事项排列,所以给你的排列要转化一下:例如:
10
3 1 2 4 9 5 10 6 8 7
意思是:1事项在第三个时间位置发生,2事项在第一个时间发生,以此类推……
转化为:2 3 1 4 6 8 10 9 5 7

转换完后,按照最长公共子序列的模板求解。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 25;int dp[N][N];int goal[N];int num[N];int main() {int n,pos;scanf("%d",&n);for(int i = 1; i <= n; i++) {scanf("%d",&pos);goal[pos] = i;}while(scanf("%d",&pos) != EOF) {num[pos] = 1;for(int i = 2; i <= n; i++) {scanf("%d",&pos);num[pos] = i;}memset(dp,0,sizeof(dp));for(int i = 1; i <= n; i++) {for(int j = 1; j <= n; j++) {if(num[j] == goal[i]) {dp[i][j] = dp[i-1][j-1]+1;}else {dp[i][j] = max(dp[i-1][j],dp[i][j-1]);}}}printf("%d\n",dp[n][n]);}return 0;}


0 0
原创粉丝点击