HDU-1053:Advanced Fruits(LCS+路径保存)
题意:将两个字符串合成一个串,不改变原串的相对顺序,可将相同字母合成一个,求合成后最短的字符串。
题解:LCS有三种状态转移方式,将每个点的状态转移方式记录下来,再回溯。
#include <bits/stdc++.h> using namespace std; const double EPS = 1e-6; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 100 + 10; char s[maxn], t[maxn]; int slen, tlen; int dp[maxn][maxn], p[maxn][maxn]; void LCS() { memset(dp, 0, sizeof(dp)); for(int i = 0; i <= slen; i++) p[i][0] = 1; for(int i = 0; i <= tlen; i++) p[0][i] = -1; for(int i = 1; i <= slen; i++){ for(int j = 1; j <= tlen; j++){ if(s[i] == t[j]){ dp[i][j] = dp[i-1][j-1] + 1; p[i][j] = 0; } else if(dp[i-1][j] >= dp[i][j-1]){ dp[i][j] = dp[i-1][j]; p[i][j] = 1; } else{ dp[i][j] = dp[i][j-1]; p[i][j] = -1; } } } } void PrintLcs(int i, int j) { if(!i && !j) return ; if(p[i][j] == 0){ PrintLcs(i-1, j-1); putchar(s[i]); } else if(p[i][j] == 1){ PrintLcs(i-1, j); putchar(s[i]); } else if(p[i][j] == -1){ PrintLcs(i, j-1); putchar(t[j]); } } int main() { while(scanf("%s%s", s + 1, t + 1) != EOF){ slen = strlen(s + 1); tlen = strlen(t + 1); LCS(); PrintLcs(slen, tlen); puts(""); } return 0; }