HDU 1159 Common Subsequence (最长公共子序列)

  文章作者:ktyanny 文章来源:ktyanny 转载请注明,谢谢合作。  

  

   ktyanny本打算复习考试周研究一下动态规划,今天早上起得很晚,爬起来就想起这件事了,找到一个最水的最长公共子序列的题目,其实算是裸题了。

  题目的意思就是给出两个串x和y,让你输出出他们的最长公共子序列(LCS)的长度。于是在纸上模拟了半晌,终于搞懂了记忆化(memoization)是怎么个原理了。下面讲讲LCS的过程吧:

   


LCS
- LENGTH(X, Y, m, n)
   
for  i ←  1  to m    do   c[i,  0 ] ←  0
   
for  j ←  0  to n      do  c[ 0 , j] ←  0
   
for  i ←  1  to m     do
         
for  j ←  1  to n  do
              
if  xi  =  yj
              then c[i, j] ← c[i 
-   1 , j  -   1 +   1  
             
else   if  c[i  -   1 , j] ≥ c[i, j  -   1 ]
               then c[i, j] ← c[i 
-   1 , j]
                
else  c[i, j] ← c[i, j  -   1 ]
return  c and b

 

  好!根据上面的伪代码,自己跟踪一下c[i][j]数组的变化情况问题就变得很清晰了。

 下面是1159的ac代码

  46MS C++

#include  < iostream >
#include 
< string .h >
using   namespace  std;

const   int  MAX  =   1000 ;

int  c[MAX + 5 ][MAX + 5 ];
int  lcs( char   * x,  char   * y,  int  c[][MAX + 5 ])
{
    
int  i, j, m  =  strlen(x), n  =  strlen(y);
    
for (i  =   0 ; i  <  m; i ++ ) c[i][ 0 =   0 ;
    
for (i  =   0 ; i  <  n; i ++ ) c[ 0 ][i]  =   0 ;
    
for (i  =   0 ; i  <  m; i ++ )
    {
        
for (j  =   0 ; j  <  n; j ++ )
        {
            
if (x[i]  ==  y[j])
                c[i
+ 1 ][j + 1 =  c[i][j]  +   1 ;
            
else
                
if (c[i][j + 1 >=  c[i + 1 ][j])
                    c[i
+ 1 ][j + 1 =  c[i][j + 1 ];
                
else
                    c[i
+ 1 ][j + 1 =  c[i + 1 ][j];
        }
    }
    
return  c[m][n];
}

int  main()
{
    
char  x[MAX];
    
char  y[MAX];
    
while (cin  >>  x  >>  y)
        cout 
<<  lcs(x, y, c)  <<  endl;
    
return   0 ;
}

 

 

  下面记下流水账。 

  上个星期伙食吃超支了,吃了两次麦当劳,打了一次火锅,光了四次超市,昨天还去地下商场吃大家乐。再这样逍遥下去的话我就木有米吃饭了。昨晚睡觉也很玄,可能吃太好了。是这个学期第二次梦到我有一部笔记本了,不过结局好惨,居然被我玩到着火了,囧……第一次梦到自己有笔记本是妈妈说同意我用自己的奖学金买笔记本。等奖学金拿到手的时候, 我倒是想买个电磁炉,因为预测到寒假的饭菜肯定很难啃,想自己学着炒菜啊,好吃又便宜的。嘎嘎……

你可能感兴趣的:(sequence)