动态规划之最长01子序列问题

 问题描述

  • 现在有两个字符串已知
  • 要求的他们最长的公共子序列长度
  • 例如csdnblog和belong的最长公共子序列是4,由于它们都含有blog这一个子序列

 解题思路与算法思想

既然使用动态规划算法,那么算法的核心就是将问题分布
	这一点和数学归纳法有点相似
假设含有字符串xc长度为a
有字符串y长度为b
现在在比较x的前a1位和y的前b1位置的最长公共子序列
	那么我们需要假设已知之前的所有状态,如图:

《动态规划之最长01子序列问题》
 程序模型的建立

  • 先将数据输入
  • 建立转移方程:
如果当前的两个字符相同
	那么加一
如果不同
	在其他状态之中选择一个比较大的
  • 之后通过递归+记忆的方式计算出匹配的最大字符串
  • 最后将匹配的个数输出

 数据结构的选用
选用string去储存这两个字符串

 程序设计流程
输入数据
进行计算
输出结果

 程序设计伪码算法

	if((c<0)||(d<0))
	{
		return 0 ;
	}
	
	if(bb[c][d]!=-1)
	{
		return bb[c][d] ;
	}
	
	
	if(a[c] == b[d] )
	{
		bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
		return bb[c][d]  ;
	}
	else
	{
		bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
		return bb[c][d]  ;
	
	}

 源程序编码清单

#include<iostream>
#include<string>
#include<vector>
using namespace std ;
int find_num(string a ,string b ,int c ,int d) ;
vector< vector<int> > bb ;
int main(void)
{
	string a ;
	string b ;
	vector<int>aa ;
	
	
	cin>>a ;
	cin>>b ;
	for(int i = 0 ;i<b.size() ;i++)
	{
		aa.push_back(-1) ;
	}
	for(int i = 0 ;i<a.size() ;i++)
	{
		bb.push_back(aa) ;
	}
	printf("%d",find_num(a,b,a.size()-1,b.size()-1)) ;
}
int find_num(string a ,string b ,int c ,int d) 
{
	if((c<0)||(d<0))
	{
		return 0 ;
	}
	
	if(bb[c][d]!=-1)
	{
		return bb[c][d] ;
	}
	
	
	if(a[c] == b[d] )
	{
		bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
		return bb[c][d]  ;
	}
	else
	{
		bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
		return bb[c][d]  ;
	
	}
}

 程序输入、输出

输入:
csdnblog
belong
输出:
4

输入输出文件,或程序运行结果截图
《动态规划之最长01子序列问题》
 时间与空间复杂度分析
时间复杂度是n^2
 程序使用说明

 总结与完善

    原文作者:算法
    原文地址: https://www.twblogs.net/a/5bd3a6d72b717778ac20a588
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞