题意:
给一个标准时间,给若干个排序时间,问最长公共子序列长度。
解析:
状态转移方程:
if (time[i - 1] == num[j - 1])
{
dp[i][j] = dp[i - 1][j - 1] +1;
}
else
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
本题需要注意的是题目给的数字是排序点,比如4 1 2 3 表示的是第1个点在第4个位置上,第2个点在1上,3在2上,4在3上。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
using namespace std;
const int maxn = 30 + 10;
int Time[maxn];
int num[maxn];
int dp[maxn][maxn];
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int n;
scanf("%d", &n);
int x;
for (int i = 1; i <= n; i++)
{
scanf("%d", &x);
Time[x] = i;
}
while (scanf("%d", &x) != EOF)
{
num[x] = 1;
for (int i = 2; i <= n; i++)
{
scanf("%d", &x);
num[x] = i;
}
memset(dp, 0, sizeof(dp));
for (int i = 2; i <= n + 1; i++)
{
for (int j = 2; j <= n + 1; j++)
{
if (Time[i - 1] == num[j - 1])
{
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 + 1][n + 1]);
}
return 0;
}