题目大意:
经典的求最长公共子序列问题。
解题思路:
准确找出状态转移方程即可。
*状态转移:
*1、if(str[i] == str[j]) dp[i][j] = dp[i-1][j-1]+1
*2、else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
有状态转移方程可以看出,其实当前的dp[i][j]只跟前一行还有当前行有关,所以我们可以只用dp[2][MAX_LEN]即可,就是所谓的滚动数组。这道题目有点小奇葩,当我的数组开到100005的时候,报TLE。
代码:
![lcd](http://yuguichun.com/wp-content/uploads/2012/02/lcd-300x177.png)
/*
*状态转移:
*1、if(str[i] == str[j]) dp[i][j] = dp[i-1][j-1]+1
*2、else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
*/
#include
#include
using namespace std;
const int MAX_LEN = 1005;
int dp[2][MAX_LEN];
char str1[MAX_LEN], str2[MAX_LEN];
int main(void)
{
str1[0] = str2[0] = '1';
while(scanf("%s %s", str1+1, str2+1) == 2)
{
memset(dp, 0, sizeof(dp));
int len1 = strlen(str1);
int len2 = strlen(str2);
for(int i = 1; i < len1; i++)
{
for(int j = 1; j < len2; j++)
{
if(str1[i] == str2[j])
dp[1][j] = dp[0][j-1] + 1;//dp[1][x]是当前行,dp[0][x]是上一行
else
{
if(dp[1][j-1] > dp[0][j])
dp[1][j] = dp[1][j-1];
else
dp[1][j] = dp[0][j];
}
}
memcpy(dp[0], dp[1], sizeof(dp[1]));
}
printf("%d\n", dp[1][len2-1]);
}
return 0;
}