题目地址:http://poj.org/problem?id=2127
Description
Input
Output
Sample Input
5 1 4 2 5 -12 4 -12 1 2 4
Sample Output
2 1 4
状态dp[i][j]表示seq1[i]从1到i与seq2[j]从1到j并以j为结尾的LCIS的长度
状态转移方程:
dp[i][j] = max(dp[i][k]) + 1, if seq1[i] ==seq2[j], 1 <= k < j
dp[i][j] = dp[i-1][j], if seq1[i] != seq2[j]
#include <stdio.h> #include <string.h> #define MAX 501 typedef struct path{ int x, y; }Pre; int seq1[MAX], seq2[MAX]; int len1, len2; int dp[MAX][MAX]; //状态dp[i][j]记录seq1前i个与seq2前j个并以seq2[j]为结尾的LCIS的长度 Pre pre[MAX][MAX];//pre[i][j]记录前驱 int path[MAX];//根据pre[i][j]回溯可得到LCIS int index; int LCIS(){ int i, j; int max, tx, ty; int id_x, id_y; int tmpx, tmpy; //给dp[i][j]、pre[i][j]置初值 memset(dp, 0, sizeof(dp)); memset(pre, 0, sizeof(pre)); for (i = 1; i <= len1; ++i){ max = 0; tx = ty = 0; for (j = 1; j <= len2; ++j){ //状态转移方程 dp[i][j] = dp[i-1][j]; pre[i][j].x = i - 1; pre[i][j].y = j; if (seq1[i] > seq2[j] && max < dp[i-1][j]){ max = dp[i-1][j]; tx = i - 1; ty = j; } if (seq1[i] == seq2[j]){ dp[i][j] = max + 1; pre[i][j].x = tx; pre[i][j].y = ty; } } } //找到LCIS最后的数字的位置 max = -1; for (i = 1; i <= len2; ++i){ if (dp[len1][i] > max){ max = dp[len1][i]; id_y = i; } } id_x = len1; index = 0; while (dp[id_x][id_y] != 0){ tmpx = pre[id_x][id_y].x; tmpy = pre[id_x][id_y].y; //若找到前一对公共点,则添加进路径 if (dp[tmpx][tmpy] != dp[id_x][id_y]){ path[index] = seq2[id_y]; ++index; } id_x = tmpx; id_y = tmpy; } return max; } int main(void){ int i; while (scanf("%d", &len1) != EOF){ for (i = 1; i <= len1; ++i) scanf("%d", &seq1[i]); scanf("%d", &len2); for (i = 1; i <= len2; ++i) scanf("%d", &seq2[i]); printf("%d\n", LCIS()); --index; if (index >= 0) printf("%d", path[index]); for (i = index - 1; i >= 0; --i){ printf(" %d", path[i]); } printf("\n"); } return 0; }