算法设计与分析期末复习(二)

news2024/10/6 4:05:50

动态规划

基本思想:把求解的问题分成许多阶段或多个子问题,然后按顺序求解各个子问题。**前一个子问题的解为后一个子问题的求解提供了有用的信息。**在求解任何一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其它局部解,依次解决各子问题,最后一个子问题就是问题的解。

对于一个多阶段过程问题,最优策略是否存在,不仅依赖于该问题是否有最优子结构性质,而能否采取动态规划的方法,还要看该问题的子问题是否具有重叠性质。
最优子结构性质:原问题的最优解包含了其子问题的最优解。
子问题重叠性质:每次产生的子问题并不总是新问题,有些子问题被反复计算多次。

动态规划基本步骤

  1. 找出最优解的性质,并刻画其结构特征。
  2. 递归地定义最优值。
  3. 以自底向上的方式计算出最优值。
  4. 根据计算最优值时得到的信息,构造最优解。

矩阵连乘问题

  • 穷举法
  • 动态规划法
    将矩阵连乘积Ai Ai+1Aj,简记为A[i:j],i≤j,考虑计算A[i:j]的最优计算次序。
for(int *p,int n,int **t,int **s){
	for(int i = 1; i <= n; i++) m[i][i] = 0;
	for(int r = 2; r<= n; r++){
		for(int i=1; i <= n-r+1; i++){
			int j = i+r-1;
			m[i][j] = m[i][i] + m[i+1][j] + p[i-1]*p[i]*p[j];
			s[i][j] = i;
			for(int k=i+1; k < j; k++){
				int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
				if(t <= m[i][j]){
					m[i][j] = t;
					s[i][j] = k;
				}
			}
		}
	}
}

算法的计算时间上界O(n3),所占用的空间为O(n2)

最长公共子序列

由最长公共子序列问题的最优子结构性质建立子问题最优值的递归关系,用c[i][j]记录最长公共子序列的长度。
当i=0或j=0时,空序列是A和B的最长公共子序列。因此C[i][j]=0。
在这里插入图片描述
由于在所考虑的子问题空间中,总有θ(mn)个不同的子问题,因此用动态规划自底向上计算最优值能提高算法的效率。

void LCSLength(int m,int n,char *x,char *y,int **c,int **b){
	int i,j;
	for(i=1; i<=m; i++)	c[i][0]=0;
	for(i=1; i<=n; i++) c[0][i]=0;
	for(i=1; i<=m; i++){
		for(j=1; j<=n; j++){
			if(x[i]==y[j]){
				c[i][j] = x[i-1][j-1] + 1;
				b[i][j] = 1;
			}else if(c[i-1][j] >= c[i][j-1]){
				c[i][j] = c[i-1][j];
				b[i][j] = 2;
			}else{
				c[i][j] = c[i][j-1];
				b[i][j] = 3;
			}
		}
	}
}

构造最长公共子序列

void LCS(int i,int j,char *x,int **b){
	if(i==0 || j==0) return;
	if(b[i][j] == 1){
		LCS(i-1,j-1,x,b);
		printf("%d ",x[i]);
	}else if(b[i][j] == 2){
		LCS(i-1,j,x,b);
	}else{
		LCS(i,j-1,x,b);
	}
}

根据序列x,y,建立两个(m+1)x(n+1)的二维表C和二维表B,分别存放搜索过程中得到的子序列的长度和状态。
在这里插入图片描述
在这里插入图片描述

动态规划求解0-1背包问题

在这里插入图片描述
令V(i,j)表示前i个物品,能够装入容量为j的背包中的物品最大值。
V(i,0) = 0; 背包容量为0
V(0,j) = 0; 没有物品

  • 如果当前物品i重量大于背包容量wi>j,V(i,j) = V(i-1,j);
  • 如果当前物品重量小于等于背包容量wi≤j,V(i,j) = max{V(i-1,j) , V(i-1,j-wi)+vi};
void KnapSack(int n,int w[],int v[][]){
	int i,j;
	for(i=0; i<=n; i++)	v[i][0] = 0;
	for(j=0; j<=c; j++) v[0][j] = 0;
	for(i=1; i<=n; i++){
		for(j=1; j<=c; j++){
			if(w[i] > j){
				v[i][j] = v[i-1][j];
			}else{
				v[i][j] = max{v[i-1][j] , v[i-1][j-w[i]]+v[i]};
			}
		}
	}
	// 求装入背包的物品
	j = c;
	for(i=n;i>=0;i--){
		if(v[i][j] > v[i-1][j]){
			x[i] = 1;
			j = j - w[i];
		}else{
			x[i] = 0;
		}
	}
	return v[n][c];
}

贪心算法

贪心算法总是做出在当前看来最好的选择,即所作的选择是局部最优解。
希望从局部的最优解得到整体最优解
采用逐步构造最优解的方法。在每个阶段,都作出一个看上去最优的策略(在一定的标准下)。决策一旦做出,就不可以再更改。

贪心算法求解问题的基本要素

  • 最优子结构性质:原问题的最优解包含了子问题的最优解。
  • 贪心选择性质:原问题的最优解可以由一系列局部最优的选择来获得。

贪心算法与动态规划算法之间的差异

  • 相同点:都具有最优子结构性质
  • 区别:动态规划算法每步所做出的选择往往依赖于相关子问题的解,只有解除相关子问题才能做出选择。 贪心算法仅在当前状态下做出最好选择,即局部最优选择,但不依赖于子问题的解。
  • 贪心:自顶向下
  • 动态规划:自底向上

活动安排问题

已知n个活动E={1,2,…,n}要求使用同一资源,第k个活动要求的开始时间和结束时间为sk和fk,其中sk<fk,活动k与活动j相容,sk≥fj或sj≥fk
活动安排问题就是在所给的活动集合中选出最大的相容活动子集。

基本思路
在安排时将结束时间早的活动尽量往前安排,好给后面的活动安排留出更多的空间,从而达到安排最多活动的目标。
贪心准则:在未安排的活动中挑选结束时间最早的活动安排

首先将安排的11个活动的开始时间和结束时间按结束时间的非减次序列排序:
在这里插入图片描述
在这里插入图片描述

各活动的开始时间和结束时间已经按结束时间的非减序排列了。
public static void greedySelector(int s[], int f[], bool a[]){
	int n = s.length - 1;
	a[0] = true;
	int j = 0; //已经安排的最后一个活动
	int count = 1;
	for(int i=1; i<=n; i++){
		if(s[i] >= f[j]){
			a[i] = true;
			j = i;
			count++;
		}else{
			a[i] = false;
		}
	}
	return count;
}

0-1背包问题不能用贪心算法求解,因为0-1背包问题无法保证最终能将背包装满,部分闲置的背包空间使单位背包空间的价值降低了。

用贪心算法解决背包问题

在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包。
在这里插入图片描述
用贪心算法解决背包问题的基本思想:

  1. 计算每种物品单位重量的价值vi/wi,然后依贪心选择策略,尽可能多的将单位重量价值最高的物品装入背包。若这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直进行下去,直到使背包装满为止,若最后一个物品不能全部装入,仅装其一部分即可。
void Knapsack(int n, float M,float v[], float w[], float x[]){
	sort(n,v,w);//将物品按单位重量价值排序
	int i;
	for(i=1; i<=n; i++) x[i] = 0;
	float c = M;
	for(i=1; i<=n; i++){
		if(w[i] > c){
			break;
		}
		x[i] = 1;
		c = c-w[i];
	}
	if(i<=n){
		x[i] = c/w[i];
	}
}

该算法的主要计算时间在于将各种物品依此按单位重量价值从大到小排序,因此算法的计算时间上界为O(nlogn)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/618113.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux面试题汇总

Linux面试题汇总 网络拓展Linux 概述什么是LinuxUnix和Linux有什么区别&#xff1f;什么是 Linux 内核&#xff1f;Linux的基本组件是什么&#xff1f;Linux 的体系结构BASH和DOS之间的基本区别是什么&#xff1f;Linux 开机启动过程&#xff1f;Linux系统缺省的运行级别&#…

javaScript蓝桥杯----外卖给好评

目录 一、介绍二、准备三、⽬标四、代码五、完成 一、介绍 外卖是现代⽣活中必备的⼀环。收到外卖后&#xff0c;各⼤平台软件常常会邀请⽤户在⼝味&#xff0c;配送速度等多个⽅⾯给与评分。在 element-ui 组件中&#xff0c;已经有相应的 Rate 组件&#xff0c;但是已有组件…

前端052_单点登录SSO_单点退出系统

单点退出系统 1、 需求分析2、EasyMock 添加退出系统模拟接口3、定义Api调用退出接口4、定义 Vuex 退出行为1、 需求分析 所有应用系统退出,全部发送请求到当前认证中心进行处理,发送请求后台删除用户登录数据,并将 cookie 中的用户数据清除。 2、EasyMock 添加退出系统模拟…

大数据分析案例-基于LightGBM算法构建银行客户流失预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

第四章:运算符

第四章&#xff1a;运算符 4.1&#xff1a;算术运算符 ​ 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达值&#xff0c;对数值或表达式进行加()、减(-)、乘(*)、除(/)、取模(%)运算。 运算符名称作用示例加法运算符计算两个值或表达式的和SE…

chatgpt赋能python:Python如何遍历文件:一篇完整的指南

Python如何遍历文件: 一篇完整的指南 在进行文件操作时&#xff0c;遍历文件是相当普遍的需求。Python中提供了多种方法来遍历文件夹和文件&#xff0c;包括os模块&#xff0c;glob模块和os.walk方法。这篇文章将会介绍这些方法及其应用。 什么是遍历文件&#xff1f; 遍历文…

使用 ConstraintLayout

ConstraintLayout解析 1.前言2.了解ConstraintLayout3.基本用法3.1 看一个布局3.2再看一个布局 1.前言 你是不是一直不敢用ConstraintLayout&#xff0c;是以为属性太多太复杂&#xff1f;你心理上的惰性&#xff0c;畏惧它。它其实很好用很强大&#xff0c;如果要用就需要一个…

Day_40关于图的总结

一. 实际问题的抽象与建模 如果我们需要研究一个实际问题&#xff0c;首先第一步就是对这个实际问题进行抽象&#xff0c;抽象是从众多的事物中抽取出共同的、本质性的特征&#xff0c;而舍弃其非本质的特征的过程。具体地说&#xff0c;抽象就是人们在实践的基础上&#xff0c…

Java中的金钱陷阱

前言 有多少小伙伴是被标题 骗 吸引进来的呢&#xff0c;我可不是标题党&#xff0c;今天的文章呢确实跟”金钱“有关系。 但是我们说的不是过度追求金钱而掉入陷阱&#xff0c;而是要说一说在Java程序中&#xff0c;各种跟金钱运算有关的陷阱。 日常工作中我们经常会涉及到…

chatgpt赋能python:Python字幕滚动:如何让你的视频内容更吸引人

Python字幕滚动&#xff1a;如何让你的视频内容更吸引人 如果你是一位视频创作者&#xff0c;你可能知道如何通过字幕来增加你的视频的吸引力。Python提供了一种简单且高效的方法来制作字幕滚动。字幕滚动是指将文字逐个显示在视频下方&#xff0c;以帮助观众跟上视频的进展。…

让我们彻底了解Maven(一)--- 基础和进阶

Maven大家都很熟悉&#xff0c;但是我们很多人&#xff0c;对它其实都是似乎很熟&#xff0c;但是又好像不熟悉的感觉&#xff0c;包括我&#xff0c;今天咱们就一起来彻底了解Maven的所有功能&#xff0c;我们从入门&#xff0c;到原理剖析&#xff0c;再到实践操作&#xff0…

chatgpt赋能python:Python如何遍历列表并提取

Python如何遍历列表并提取 在Python编程语言中&#xff0c;列表是一种非常常见的数据类型。它是一个有序的集合&#xff0c;可以存储多个元素&#xff0c;可以是任何类型的数据&#xff0c;例如整数、字符串、布尔值等等。遍历一个列表并提取其中的元素是一个基本的操作&#…

测试用例设计方法——错误猜测法

很多软件测试从业者用到的黑盒测试用例设计方法大多是等价类划分法、边界值分析法、判定表法、因果图法和正交试验法等&#xff0c;其实还有一种方法不得不提到&#xff0c;那就是错误猜测法&#xff0c;这对资深测试人员尤为重要。因为随着在产品测试的实践中对产品的了解和测…

MySQL目录结构与源码

MySQL目录结构与源码 前言一、主要目录结构二、MySQL 源代码获取 前言 本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识&#xff0c;有兴趣的小伙伴可以关注博主&#xff01;也许一个人独行&#xff0c;可以走的很快&#xff0c;但是一群人结伴而行&#xff…

Linux命令学习之文本查看命令cat、head和tail

for i in {1..100} do echo $i >> good.txt done把1到100写入到good.txt文件中。接下来使用good.txt这个文件来演示查看文本查看命令。 cat man cat可以看一下帮助使用说明&#xff0c;按q可以退出。 cat是连接文件并把文件内容输出到标准输出上。cat good.txt就可以…

Mirai 僵尸网络变体向 RCE、DDoS 开放 Tenda、Zyxel Gear

Mirai 僵尸网络的一个变体利用四种不同的设备漏洞将流行的基于 Linux 的服务器和物联网 (IoT) 设备添加到可以进行基于网络的攻击&#xff08;包括分布式拒绝服务 (DDoS) 攻击&#xff09;的僵尸网络中。 Palo Alto Networks 的 Unit 42 的一个团队观察到这个变体&#xff0c;…

【利用AI让知识体系化】Webpack 相关配置技巧

文章目录 章节一&#xff1a;了解 WebpackWebpack 是什么&#xff1f;为什么使用 Webpack&#xff1f;Webpack 的基本概念Webpack 的核心概念和实现原理 章节二&#xff1a;安装和配置 Webpack安装 Webpack配置 WebpackWebpack 的常用配置项 章节三&#xff1a;Webpack 的插件和…

企业应该如何选择适合自己的直播平台?

企业应该如何选择适合自己的直播平台&#xff1f;本文将从功能需求、可靠性与稳定性、用户体验、技术能与售后服务能力等方面进行综合考虑&#xff0c;帮助您做出明智的决策&#xff0c;或是说提供选型方面的参考。 企业在选择一家直播平台时应考虑以下因素&#xff1a; 1. 企…

2023/6/6总结

CSS 如果想要实现背景颜色渐变效果&#xff1a; left是从左边开始&#xff0c;如果想要对角线比如&#xff0c;左上角就是left top&#xff0c;渐变效果始终是沿着一条线来实现的。 下面是跟着视频教学用flex布局写的一个移动端网页&#xff1a; html代码&#xff1a; <!…

chatgpt赋能python:Python字符串:去除\n的方法和应用

Python字符串&#xff1a;去除\n的方法和应用 在Python编程中&#xff0c;字符串是非常常用的数据类型。在文本处理中&#xff0c;经常会遇到需要去除多余的换行符&#xff08;\n&#xff09;的情况。本文将介绍Python中去除\n的方法以及在实际应用中的使用。 方法一&#xf…