动态规划

一、动态规划(dynamic programming)

要点一:动态规划通常用于解决最优化问题。

要点二:最优解和最优解的值是不同的概念,最优解可以有多个,最优解的值只能有一个。

要点三:算法设计包含四个步骤:

(1)描述最优解的结构;

(2)递归定义最优解的值;

(3)按自底向上的方式计算最优解的值;

(4)由计算出的结果构造一个最优解。

要点四:应用动态规划的前提有两个:(1)最优子结构(2)重叠子序列

要点五:《算法导论(第二版)》P192

二、LCS的C++实现

最长公共子序列(Longest-Comment-Subsequence, LCS)

(一)借助数组b来构造最优解的值:

#include <iostream>
#include <stdlib.h>

using namespace std;
//说明:X,Y表示要匹配的两个序列;m,n分别表示X,Y中要进行比较的字符个数。
//由于在序列X,Y和数组c和b中,下标为0的位置都不用,所以:X,Y,c,b可以如下表示:
//X:0,1,...,m; Y:0,1,...,n; c,b:(0,1,...,m )*(0,1,...,n)。即,c和b都是m+1行n+1列

//函数LCS_LENGTH:用于计算LCS的长度(应用数组b做记录)
void LCS_LENGTH(char* X,int m,char* Y,int n,int c[][7],int b[][7])
{
	int i,j;
	
	for(i=1;i<=m;i++)
	{
		c[i][0]=0;
		b[i][0]=0;
	}
	
	for(j=0;j<=n;j++)
	{
		c[0][j]=0;
		b[0][j]=0;
	}

	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
		{
			if(*(X+i)==*(Y+j))
			{
				//c[i,j]=c[i-1,j-1]+1
				c[i][j]=c[i-1][j-1]+1;
				//↖:1;↑:2;←:3;
				//b[i,j]='↖'
				b[i][j]=1;
			}
			else if(c[i-1][j]>=c[i][j-1])
			{
				c[i][j]=c[i-1][j];
				//b[i,j]='↑'
				b[i][j]=2;
			}
			else
			{
				c[i][j]=c[i][j-1];
				//b[i,j]='←'
				b[i][j]=3;
			}
		}//for(j...)
}//LCS_LENGTH


//函数PRINT_LCS:用于构造LCS并打印出来(应用数组b)
//n:b数组的列数;i=length(X);j=length(Y)
void PRINT_LCS(int b[][7],int n,char* X,int i,int j)
{
	if(i==0||j==0)
		return;
	if(b[i][j]==1)
	{
		PRINT_LCS(b,n,X,i-1,j-1);
		cout<<*(X+i)<<" ";
	}
	else if(b[i][j]==2)
		PRINT_LCS(b,n,X,i-1,j);
	else
		PRINT_LCS(b,n,X,i,j-1);
}

//main函数(应用b)
void main()
{
	//因为表示序列的字符数组X,Y中的第一位都不用,所以用字符‘0’填充
	char X[]="0ABCBDAB";
	char Y[]="0BDCABA";
	cout<<"LCS-Programming is running!"<<endl;
	cout<<"Squence X:A B C B D A B"<<endl;
	cout<<"Squence Y:B D C A B A"<<endl;

	//设置序列X,Y的长度
	int m=7;
	int n=6;
	int i=m,j=n;
	int c[8][7],b[8][7];

	cout<<"The LCS length is being computed!"<<endl;
	LCS_LENGTH(X,m,Y,n,c,b);
	
	cout<<"The LCS:";
	PRINT_LCS(b,n,X,i,j);

	system("pause");
}

结果:

二、不借助数组b构造LCS的方法(习题15.4-2):

#include <iostream>
#include <stdlib.h>
using namespace std;
void LCS_LENGTH(char* X,int m,char* Y,int n,int c[][7])
{
	int i,j;
	
	for(i=1;i<=m;i++)
		c[i][0]=0;

	for(j=0;j<=n;j++)
		c[0][j]=0;

	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
		{
			if(*(X+i)==*(Y+j))
				c[i][j]=c[i-1][j-1]+1;
			else if(c[i-1][j]>=c[i][j-1])
				c[i][j]=c[i-1][j];
			else
				c[i][j]=c[i][j-1];
		}//for(j...)
}//LCS-LENGTH

void PRINT_LCS(int c[][7],int n,char* X,int i,int j)
{
	if(i==0||j==0)
		return;
	if(c[i-1][j-1]==c[i][j]-1||c[i-1][j]==c[i][j]-1||c[i][j-1]==c[i][j]-1)
	{
		PRINT_LCS(c,n,X,i-1,j-1);
		cout<<*(X+i)<<" ";
	}
	else if(c[i][j]==c[i-1][j])
		PRINT_LCS(c,n,X,i-1,j);
	else
		PRINT_LCS(c,n,X,i,j-1);
}

void main()
{
	cout<<"LCS-Programming is running!"<<endl;
	cout<<"Squence X:A B C B D A B"<<endl;
	cout<<"Squence Y:B D C A B A"<<endl;
	char X[]="0ABCBDAB";
	char Y[]="0BDCABA";
	int m=7;
	int n=6;
	int c[8][7]={0};
	int i=m,j=n;

	cout<<"The LCS length is being computed!"<<endl;
	LCS_LENGTH(X,m,Y,n,c);
	
	cout<<"The LCS:";
	PRINT_LCS(c,n,X,i,j);

	system("pause");
}

结果:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值