第一次写博客,以后要坚持写~~ 先说题意: 先输入n(2<=n<=20), 然后输入标准顺序 (1 2 3 ... n中的数字), 然后输入学生的输入顺序(1 2 3 ... n中的数字), 求
学生和标准顺序的最长公共子串, (如标准顺序为:4 2 3 1, 学生顺序为2 4 3 1, 则最长为3: (4 3 1), )当然这题可以用暴力法, 但是时间hold 不住, 提倡用动态规划
求最长公共子串:
动态规划求最长公共子串: 设dp[i][j]表示(分别设str1和str2)str1的最后一个字符为i和str2的最后一个字符为j, 则当i == j时,
若 str1[i] == str2[j] 则 dp[i][j] = dp[i-1][j-1]+1, 若i != j, 则dp[i][j] = max(dp[i-1][j] , dp[i][j-1]), 详细证明就不写了 很简单的。
code :
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 100
int dp[MAXN][MAXN], order[MAXN], stu[MAXN];
int main()
{
int n, tmp;
scanf("%d", &n);
for (int i = 1; i <= n; i++){
scanf("%d", &tmp);
order[tmp] = i;
}
while (scanf("%d", &tmp) != EOF)
{
stu[tmp] = 1;
for (int i = 2; i <= n; i++){
scanf("%d", &tmp);
stu[tmp] = i;
}
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
if (stu[j] == order[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;
}
/**
History Grading
4
2 3 4 1
3 4 1 2
*/