动态规划练习二: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求解出来的。
稍微说一下动态规划方程的由来:
假如输入的两个字符串分别为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;
}
#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;
}
我没有什么雄心壮志,我只想给自己和关心自己的家人和朋友一个交代,仅此而已。