ITA 动态规划2

这个题目比较难想象,因为数组下标(表格的标号)跟问题之间的关系不像之前的问题那么的明确,一个推出一个。要注意的是,e[i,j]保存在表e[1...n+1,0...n]中,第一维下标到n+1是因为有一个包含虚拟键dn的子树,我们需要计算和保存e[n+1,n]。第二维下标从0开始,是为了保存e[1,0],需要画出一个树的格式,帮助理解这些概念。所有e[i,i-1]都是包含虚拟键的



//动态规划,最优二叉查找树
//假设正在设计一个程序,用于将文章从英文翻译为法语,对于出现在文章内的每一个英文单词,
//	需要查看与它等价的法语。执行这些搜索操作的一种方式是建立一棵二叉查找树,,,
//	因为要为文章中的每个单词搜索这棵树,古故希望搜索所花费的总时间尽可能的小,
//	因此我们希望文章中出现频繁的单词呗放置在距离根部较近的地方,而且文章中可能会有些单词没有法语的翻译,
//	这些单词可能根本就不会出现在二叉查找树中。
//
//  n个关键字,对于每个关键字ki,一次搜索ki的概率为pi,,,,
//    树中还存在n+1个虚拟的关键字di,一尺搜索di的概率为qi,假设n=5个的关键字的集合上的二叉查找树的概率如下
// ,现在要求根据上表构造一棵二叉查找树,使得二叉查找树的期望搜索代价最低:
//定义e[i,j]为搜索一棵包含关键字ki,,,kj的最优二叉查找树的期望代价,最终要计算e[1,n]。。。。
//
//    当j=i-1时,只有虚拟键di-1,期望的搜索代价是e[i,i-1]=qi-1。
//
//    当j>=i时,需要从ki,...,kj中选择一个根kr,然后用关键字ki,...,kr-1来构造一棵最优二叉查找树作为其左子树,
//	并用关键字kr+1,...,kj来构造一棵最优二叉查找树作为其右子树。。。注意当一棵树成为一个节点的子树时,
//	它的期望搜索代价增加量将为该子树中所有概率的总和。对于一棵有关键字ki,...,kj的子树,定义概率的总和为:
//
//      w[i,j]=pl(l=i到j)的总和+ql(l=i-1到j的总和)
//
//  因此,有
//
//      e[i,j]=qi-1                                                         j=i-1
//
//      e[i,j]=min{e[i,r-1]+e[r+1,j]+w[i,j]}                     i<=j
//
//  另外定义root[i,j]为kr的下标r。
const int n =5;
double optimalBest(double p[], double q[], int root[][n+1])
{
	int i=0,len=0,j=0,r=0;
	double t =0.0;
	double e[n+2][n+1];
	double w[n+2][n+1];
	for(i=1;i<=n+1;++i)
	{
		e[i][i-1]=q[i-1];
		w[i][i-1]=q[i-1];
	}

	for(len=1; len <=n;++len)//内节点的个数
	{
		for(i=1;i<=n-len+1;++i)//设置起点i
		{
			j=i+len-1;//设置终点l
			e[i][j]=0x7fffffff;
			w[i][j]= w[i][j-1]+p[j]+q[j];
			for(r=i;r<=j;++r)
			{
				t=e[i][r-1]+e[r+1][j]+w[i][j];
				if(t<e[i][j])
				{
					e[i][j]=t;
					root[i][j]=r;
					cout<<"e"<<t<<endl;
					cout<<r<<endl;
				}

			}

		}

	}
	return e[1][n];

}
void printBest(int root[][n+1],int i,int j)
{
	int k=0;
	if(i<=j)
	{
		cout<<root[i][j];
		k=root[i][j];
		printBest(root,i,k-1);
		printBest(root,k+1,j);
	}

}

int main()
{
	int root[n+1][n+1];
	double p[n+1]={0,0.15,0.10,0.05,0.10,0.20};
	double q[n+1]={0.05,0.10,0.05,0.05,0.05,0.10};
	double k=optimalBest(p,q,root);
	cout<<"最小期望搜索代价:"<<k<<endl;
	printBest(root,1,n);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值