动态规划练习二:HDU ACM 1159 Common Subsequence

此题是用来求两个字符串中最长非连续子字符串长度的题目,关键在于看出动态规划方程。
稍微说一下动态规划方程的由来:
假如输入的两个字符串分别为s1和s2,长度分别是len1和len2.我构造一个二维数组f[len1][len2].其中二维数组中的元素f[i][j]的意义是:
字符串s1的子串s1[0.1.2....i]和字符串s2的子串s2[0.1.2....j]中的最长非连续子字符串长度。根据f数组的含义,可以构造出动态方程如下:
f[i][j] =  f[i-1][j-1] + 1  (s1[i] == s2[j])
f[i][j] = max{f[i][j-1],f[i-1][j]} (s1[i] != s2[j])
可见f[i][j]只是跟其左前方的三个元素有关,只要规定好求f数组的顺序,就可以利用dp的方法把f数组求出,在求f数组的过程中,只需要把f中的最大值求出来即可。
在下面的代码中,我是先求出了f的第一列和第一行,然后用dp的方法根据动态规划方程把f求解出来的。
#include <iostream>
#include 
<string>
using namespace std;

int mymax(int a,int b)
{
    
return a>b?a:b;
}

int main()
{
    
string s1,s2;
    
int len1,len2;
    
int **f;
    
int max;
    
int i,j;
    
int t;
    
while(cin>>s1>>s2)
    
{
        len1 
= s1.size();
        len2 
= s2.size();
        
//assign new space for 2-D array f
        f = new int*[len1];
        
for(i = 0;i < len1;++i)
            f[i] 
= new int[len2];

        max 
= 0;
        
//注意在求解f数组的过程中,顺序是很重要的
        
//每更新一次f中的数据,就要记得更新max的值
        if(s1[0== s2[0])
        
{
            f[
0][0= 1;
            max 
= 1;
        }

        
else
            f[
0][0= 0;

        
for(i = 1;i < len2;++i)
        
{
            
if(s1[0== s2[i])
                f[
0][i] = 1;
            
else
                f[
0][i] = mymax(0,f[0][i-1]);
            
if(f[0][i] > max)
                max 
= f[0][i];
        }

        
for(i = 1;i < len1;++i)
        
{
            
if(s1[i] == s2[0])
                f[i][
0= 1;
            
else
                f[i][
0= mymax(0,f[i-1][0]);
            
if(f[i][0> max)
                max 
= f[i][0];
        }


        
for(i = 1;i < len1;++i)
        
{
            
for(j = 1;j < len2;++j)
            
{
                
if(s1[i] == s2[j])
                    f[i][j] 
= f[i-1][j-1+ 1;
                
else
                    f[i][j] 
= mymax(f[i-1][j],f[i][j-1]);
                
if(f[i][j] > max)
                    max 
= f[i][j];
            }

        }

        cout
<<max<<endl;
        
//release the space for 2-D array f
        for(i = 0;i < len1;++i)
            delete f[i];
        delete []f;
    }

    
return 0;
}

posted on 2009-09-18 21:01  笔记  阅读(532)  评论(0编辑  收藏  举报

导航