第一次寫博客,以後要堅持寫~~ 先說題意: 先輸入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
*/