Brief Description:
一个历史考试,有n个历史事件, 它们之间的年份是不同的,要学生把这些事件按照正确的顺序排列出来。有两种记分方式,采用的是第二种: 假设有历史事件1,2,3,4, 它们正确的时间顺序是1,2,3,4, 然后假设学生的答案是1,3,2,4, 那么按照相对顺序正确的数量,答对了三个(1,2,4或者1,3,4),也就是它与正确答案的最长公共子序列长度是3,便是答对的数量。
Analyse:最长公共子序列模板题,但是这题的输入是个很大的坑,他的输入是按照顺序,事件1是排在第几位,事件2是排在第几位......, 所以要先把输入转换成正确的顺序。
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#define INF 0x7fffffff
#define SUP 0x80000000
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int N=100007;
int st[22],t[22];
int dp[22][22];
int main()
{
int n;
int id;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&id);
st[id]=i;
}
while(scanf("%d",&id)==1)
{
t[id]=1;
for(int i=2;i<=n;i++)
{
scanf("%d",&id);
t[id]=i;
}
mem(dp,0);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(st[i]==t[j])
dp[i][j]=dp[i-1][j-1]+1;
else
{
dp[i][j]=max(dp[i][j],max(dp[i-1][j],dp[i][j-1]));
}
}
}
printf("%d\n",dp[n][n]);
}
return 0;
}
原文:http://blog.csdn.net/code_or_code/article/details/44749105