【HDU】 1159 Common Subsequence

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159

现在逐渐对dp开始有感觉了。

     本题dp的思路大约来自于最初学习最长不降子序列的思想,以一个字符串为基准,另一个字符串在匹配过程中用一个dp数组去记录当前位置的最优状态。dp问题最难的在于转移方程。我们想象下,dp数组中记录了从匹配起始到该点最大的匹配长度,那么每次遇见str[i]==str[j]的时候,dp值肯定要在前面的基础上累加;而如果不相同的话,取前面最大的。

     这里说的“前面”还是一个很模糊的概念,因为涉及到两个字符串,那么前面究竟是那个呢?

    第一个是不相等的情况:取两个叉线中的最大值,因为每次都要取到目前这个状态的最优情况,那么到目前 i <-> j 之前的状态肯定是 i-1 <-> j 和 i <-> j-1.

    第二个是相等的情况:他前面的情况就是i-1 <-> j-1.

 

Common Subsequence
 1 /*
 2     最长不降子序列的改编版,其实本质也是dp
 3     当沿着两个字符串进行匹配的时候每次都记录当前位置的最优状态,并适时更新;
 4      即:
 5      1、当str1[i]==str2[j]:dp[i][j] = dp[i-1][j-1]+1; 
 6      2、否则:dp[i][j] = max(dp[i-1][j] ,dp[i][j-1]);
 7 */
 8 #include <iostream>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <string>
13 #include <cmath>
14 #include <algorithm>
15 #include <iomanip>
16 #define MAXN 1001
17 using namespace std;
18 char pat[MAXN], sub[MAXN];
19 int dp[MAXN][MAXN];
20 
21 int main()
22 {
23     int i, j, lena, lenb;
24     while(~scanf("%s %s",pat,sub)){
25             lena = strlen(pat);
26             lenb = strlen(sub);
27             memset(dp,0,sizeof(dp));
28             for(i=1; i<=lena; ++i){   
29                    for(j=1; j<=lenb; ++j){
30                          if(pat[i-1] == sub[j-1])  dp[i][j] = dp[i-1][j-1]+1;
31                          else dp[i][j] = dp[i-1][j] > dp[i][j-1] ? dp[i-1][j] : dp[i][j-1];
32                    }
33             }
34 
35             printf("%d\n",dp[lena][lenb]);
36     }
37     return 0;
38 }
posted on 2012-08-15 21:44  Yuna_  阅读(59)  评论(0编辑  收藏  举报