poj 2250 Compromise(区间dp)
题目链接:http://poj.org/problem?id=2250
思路分析:最长公共子序列问题的变形,只是把字符变成了字符串,按照最长公共子序列的思路即可以求解。
代码如下:
#include <stdio.h> #include <string.h> #define IsEqual(a, b) strcmp((a), (b)) == 0 enum { Left, Up, UpAndLeft }; int XLen, YLen; const int MAX_N = 100 + 10; char X[MAX_N][35], Y[MAX_N][35]; int dp[MAX_N][MAX_N], r[MAX_N][MAX_N]; void PrintWords(int i, int j) { if (i == 0 || j == 0) return; if (r[i][j] == UpAndLeft) { PrintWords(i - 1, j - 1); if (i == XLen && j == YLen) printf("%s",X[i]); else printf("%s ", X[i]); } else if (r[i][j] == Up) PrintWords(i - 1, j); else PrintWords(i, j - 1); } void Lcs( int XLen, int YLen ) { for (int i = 1; i <= XLen; ++i) dp[i][0] = 0; for (int j = 0; j <= YLen; ++j) dp[0][j] = 0; for (int i = 1; i <= XLen; ++i) for (int j = 1; j <= YLen; ++j) { if (IsEqual(X[i], Y[j])) { dp[i][j] = dp[i - 1][j - 1] + 1; r[i][j] = UpAndLeft; } else if (dp[i - 1][j] >= dp[i][j - 1]) { dp[i][j] = dp[i - 1][j]; r[i][j] = Up; } else { dp[i][j] = dp[i][j - 1]; r[i][j] = Left; } } } int main() { XLen = YLen = 1; while (scanf("%s", X[XLen]) != EOF) { memset(dp, 0, sizeof(dp)); memset(r, -1, sizeof(r)); while (1) { scanf("%s", X[++XLen]); if (strcmp("#", X[XLen]) == 0) { XLen--; break; } } while (1) { scanf("%s", Y[YLen++]); if (strcmp("#", Y[YLen - 1]) == 0) { YLen -= 2; break; } } Lcs(XLen, YLen); PrintWords(XLen, YLen); printf("\n"); XLen = YLen = 1; } return 0; }