动态规划练习二:HDU ACM 1159 Common Subsequence
2009-09-18 21:01
375 查看
此题是用来求两个字符串中最长非连续子字符串长度的题目,关键在于看出动态规划方程。
稍微说一下动态规划方程的由来:
假如输入的两个字符串分别为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)
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;
}
稍微说一下动态规划方程的由来:
假如输入的两个字符串分别为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)
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;
}
相关文章推荐
- 字符串 并且 动态规划练习二:HDU ACM 1159 Common Subsequence
- ACM学习历程—HDU 5534 Partial Tree(动态规划)
- 【动态规划】HDU 5492 Find a path (2015 ACM/ICPC Asia Regional Hefei Online)
- hdu 1159 Palindrome(回文串) 动态规划
- hdu 1159:Common Subsequence(动态规划)
- HDU 1159 最长公共子序列问题 动态规划
- HDU 5898&&2016 ACM/ICPC Asia Regional Shenyang Online/ odd-even number [数位DP]【动态规划】
- [ACM_动态规划] hdu 1176 免费馅饼 [变形数塔问题]
- HDU1159 - Common Subsequence - 动态规划+字符串
- 动态规划LCS问题( HDU - 1159 Common Subsequence)
- HDU 5389 Zero Escape(动态规划)——多校练习8
- HDU 1159 Common Subsequence 动态规划
- HDU 1159 Common Subsequence(动态规划)
- HDU_1159 Common Subsequence 【动态规划】
- HDU 3555 浅谈数位动态规划逆向计数问题练习
- HDU 1159 Common Subsequence(动态规划)
- HDU-1159 Common Subsequence(动态规划)
- 【ACM训练计划】 HDU 动态规划(46道题目)倾情奉献~ 【只提供思路与状态转移方程】
- 【ACM训练计划】 HDU 动态规划(46道题目)倾情奉献~ 【只提供思路与状态转移方程】
- POJ 1458/HDU 1159 最长公共子序列 (动态规划)