【算法与设计】期末总结

news2024/7/6 18:26:05

文章目录

  • 第一章 概述
    • 算法与程序
    • 时间复杂性
    • 求上界
  • 第二章 递归与分治
    • 双递归函数——Ackerman函数
    • 分治策略
      • 大整数乘法
        • 两位×两位
        • 四位x四位
      • 三位x三位
        • 两位x六位
  • 第三章 动态规划
    • 矩阵连乘
    • 基本要素
      • 最优子结构
      • 子问题重叠
    • 备忘录
  • 第四章 贪心算法
    • 活动安排问题
    • 基本要素
      • 贪心选择性质
      • 最优子结构性质
      • 与动态规划的区别
    • 背包问题
      • 物体可分
      • 物体不可分
  • 第五章 回溯法
    • **问题的解空间**
    • 0-1背包
    • 迭代回溯
    • 0-1背包问题(树结构)
  • 期末考点

第一章 概述

算法与程序

算法:解决问题的一种方式或者一种过程。算法有若干个指令组成的有穷序列。
程序:算法用某种程序设计语言的具体实现

算法的4种性质:

  • 输入
  • 输出
  • 确定性
  • 有限性

程序可以不满足“有限性”

时间复杂性

算法复杂度的高低体现在运行该算法所需要的计算机资源的多少上。资源的多少依赖于要解决问题的规模(N)、算法的输入(I)和算法本身的函数(A)

关于时间复杂性,分为三种情况:最坏情况、最好情况和平均情况。
可操作性最好且最有实际价值的是最坏情况的时间复杂度

求上界

当N>=N0时有f(N)<=Cg(N),称为函数f(N)的一个上界是Cg(N),记作f(N)=O(g(N))
这个上界的阶越低,则评估越精确,结果越有价值

如何求上界?
1.把f(N)函数中的所有阶放大到最高阶,合并后并记为Cg(N)
2.此时f(N)<=Cg(N),把这两个函数去化简即可得条件,即n值。

例子:f(n)=3n2+10n
最高阶是n2,所有阶放大到最高阶得3n2+10n2=13n2,记为Cg(N)
此时,C=13,g(N)=n2
当3n2+10n <= 3n2+10n2时,即10n <= 10n2时,条件成立。
故n0>=1
综上,当n0=1时,C=13,f(n)=O(n2)

注意:放大方向不变,方式可以改变(即可以增大阶层且缩小系数),如3n2+10n <= 3n2+n2,此时结果的C和n0都不一样,但f(n)始终一样。

第二章 递归与分治

递归:代码效率好,但是空间效率和时间效率差

如何改进??
消除递归,有两种方式:阶乘(循环)和阶加(循环、通项公式)

双递归函数——Ackerman函数

定义:一个函数及它的一个变量由函数自身定义时

分治策略

基本思想:将问题分解为k个小规模的子问题,这些子问题相互独立且原问题相同。递归地解这些子问题,将个子问题的解合并得到原问题的解。

大整数乘法

普通乘法的时间复杂度是O(n2)
通过分支策略可达到O(n1.59)

两位×两位

步骤:
1.两位数分出高低位
2.套用公式求p,q,r

遇到负数,高低位都带符号
如-23:高位-2,低位-2。至此,-23=(-2)*10+(-3)

最简的分治(递归出口):一位x一位

四位x四位

一直递归,直到满足出口

三位x三位

往前补0,公式不变

两位x六位

补零或者把六位拆成3个两位

第三章 动态规划

动态规划分治
分解子问题分解子问题
子问题相互依赖子问题相互独立

基本思想:
分解成子问题求解时,有些子问题被重复计算许多次。用一个记录所有已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量的重复计算。

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

矩阵连乘

题目背景:
若两矩阵相乘,需满足第一矩阵的行=第二矩阵的列
即Amxn X Bpxq的条件为n==p
此时,乘法次数为=m x n x q

连乘次序会影响乘法次数

按照上述步骤:
1.最优解及其结构性质:最小乘法次数 及 最小乘法次数的断开处
记A[i:j]是AiAi+1…Aj
问题:A[1:n],可以在k=1,2,⋯n−1处断开,若A[1:n]最优,则A[1:k]与A[k+1:n]也最优

2.建立递归关系
记A[i:j],其中1≤i≤j≤n,最少乘法次数记m[i][j]
(1)当i=j时→ A[i:i] →指A[i] 本身→乘法次数为0,即 m[i][j]=0
(2)当i<j时, 在k处断开, k可以取值i, i+1, ∙∙∙, j−1,在某k处乘法次数最少

在这里插入图片描述
定义数组p存储矩阵信息
p[0]为第1矩阵的行
p[1]为第1矩阵列(也为第2矩阵行)
p[2]为第2矩阵列(也为第3矩阵行)
p[3]为第3矩阵列(也为第4矩阵行)

p[n]为第n矩阵列

3.计算最优值
对于结果的存储,使用m表存储最小乘法次数(即最优值),用s表存储k值(即最优解)

代码实现:

//构造最优值
void MatrixChain(int *p, int n, int **m, int **s)//P一维数组记下标;n矩阵个数;m表;s记分段
{
	for(int i=1;i<=n;i++)
		m[i][i]=0;//对角线上都填0

	for(int r=2;r<=n;r++)//在m表中,从第2条填到第n条(对角线)
		for(int i=1;i<=n-r+1;i++)//i是行下标,从第1行开始填一个倒三角的表
		{
			int j=i+r-1;//列下标
			m[i][j]=0+m[i+1][j]+p[i-1]*p[i]*p[j];//实现递归计算,先初始化第1项,省略了m[i][i]
			s[i][j]=i;//s记分段点,此为s的初值

			for(int k=i+1;k<j;k++)//递归式从k=i+1到j-1,找最小
			{
				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;//记入划分位置
				}
			}
		}
}

4.构造最优解
算法MatrixChain只是计算出了最优值,并未给出最优解。但是MatrixChain已记录了构造最优解所需要的全部信息。s[i][j]中的数表明,最佳方式应在矩阵的何处断开。

//构造最优解
void Traceback(int i,int j,int **s)//求A[i:j]的最优解构造,利用s[][],设已知s[i][j]=k
{
	if(i==j)
		return ;//A[i:i]不必构造,递归出口

	Traceback(i,s[i][j],s);//求A[i:k]的构造,记1
    Traceback(s[i][j]+1,j,s);//求A[k+1:j]的构造,记2
	cout<<"Multiply A["<<i<<":"<<s[i][j]
		<<"]and A["<<(s[i][j]+1)<<":"<<j<<"]"<<endl;//输出Ai,k And Ak+1,j,表明在k处断开,记3
}

基本要素

最优子结构

设计动态规划算法的第一步通常是要刻画最优解的结构。
当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。

子问题重叠

在用递归算法自顶向下解此问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要解此子问题时,只是简单地用常数时间查看一下结果。

备忘录

动态规划的变形——备忘录

动态规划:保存所有子问题的解
变形:动态规划是自底向上;备忘录是自顶向下

第四章 贪心算法

工作量:贪心算法 < 动态规划
但是贪心算法的结果可能不是最优结果,因为贪心算法并不是从整体最优上加以考虑,它所做出的选择只是某种意义上的局部最优选择

所以,贪心算法的关键是贪心策略的选择

活动安排问题

该问题要求高效地安排一系列争用某一个公共资源的活动。有n个活动,开始和结束的时间si≤fi,如何安排最多个活动?

贪心策略:按结束时间递增排序,从前向后能安排则安排

例题:当前有4个活动。

i1234
s[i]1305
f[i]4567

若选择最早结束优先,能使选入活动最多
若最早开始优先,仅能安排这一个活动
若最短占用优先,则能安排这一个活动

推广:
假设要在足够多的的会场里安排一批活动,即每个活动都要被安排,并希望使用尽可能少的会场。
(1)贪心策略思路1:先在第1会场安排最多活动,其次在第2会场安排最多,……,依此类推 。
(2)贪心策略思路2:视为区间重叠问题。时间点:起点和终点。
按时间点排序起点分配1个会场,终点回收,保证此会场可重复利用
在这里插入图片描述
在这里插入图片描述

基本要素

贪心选择性质

贪心选择性质是指所求问题的整体最优解是可以通过局部最优的选择,即贪心选择达到的。
动态规划算法中,每步所做的选择往往依赖于相关子问题的解。因而只有在解出相关子问题后,才能做出选择。
而在贪心算法中,仅在当前状态下做出最好选择,即局部最优选择。然后再去解做出这个选择后产生的相应子问题。

最优子结构性质

最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

与动态规划的区别

**贪心算法:**先依据贪心策略选择并解一个子问题,再进行下一步。
**动态规划算法:**先解决所有的子问题,比较得出一个最优子问题,再进行下一步。

背包问题

问题描述:容量为c的背包,有n种物品,每种物品重w_i,价值为v_i,其中1≤i≤n,
物品不可(可以)分开。
问:如何装入使价值最大?

cnw1w2w3v1v2v3
50310203060100120

物体可分

c>0,wi>0,vi>0,1≤i≤n。找(x1,x2,⋯,xn),0≤xi≤1,可为分数,即仅取一部分,
使 ∑ i = 1 n w i ∗ x i < = c \sum_{i=1}^{n} wi*xi<= c i=1nwixi<=c 达到最大
∑ i = 1 n v i ∗ x i \sum_{i=1}^{n} vi*xi i=1nvixi

//物品可分:贪心算法 
#include <iostream>
#include <iomanip> 
using namespace std;

void Knapsack(int n, int c, int*v, int *w, double *x);

int main() 
{	
	int n=3;//物品数量 
	int c=50;//背包容量 
	int *v=new int[n+1];//价值 
	int *w=new int[n+1];//重量 
	int i;
	double *x=new double[n+1];	
	for(i=1;i<=n;i++)
		x[i]=0;	
	
	//将数据按贪心策略排序 
	v[1]=60;v[2]=100;v[3]=120;
	w[1]=10;w[2]=20;w[3]=30;
	
	Knapsack(n,c,v,w,x); 
	
	for(i=1;i<=n;i++)
	{		
		if(x[i]>0)
			cout<<"物品"<<i<<"装入"<<setiosflags(ios::fixed)<<setprecision(2)<<x[i]<<endl;
		else
			cout<<"物品"<<i<<"不装入"<<endl;
	}
		
	return 0;
}

void Knapsack(int n, int c, int*v, int *w, double *x)
{
	int i;
	
	for(i=1;i<=n;i++)
	{
		if(w[i]>c)
			break;
		else
		{
			x[i]=1;
			c=c-w[i]; 
		}			
	}	
	if(i<=n)	
		x[i]=(double)c/w[i];		
}

step1:准备
按单位价格递减排序,x[ ]初值为0,先都没选
step2:循环
按递减装入物品至不可装为止,从1检查到n
物品装入置x[i]=1,c=c−w[i]
step3:最后
将当前i物品分开,送入c/w[i]

物体不可分

其中,c>0,wi>0,vi>0,1≤i≤n,
找(x1,x2,⋯,xn),xi∈{0,1},
(物品没装xi=0,装入xi=1)
使 ∑ i = 1 n w i ∗ x i < = c \sum_{i=1}^{n} wi*xi<= c i=1nwixi<=c 达到最大
∑ i = 1 n v i ∗ x i \sum_{i=1}^{n} vi*xi i=1nvixi

根据上述步骤:
1.最优子结构性质
若(y_1,y_2,⋯,y_n)是最优解,则(y_2,⋯,y_n)是子问题的最优解

2.递归关系
m(i,j)记背包容量j,可选物品为i,i+1,⋯,n时,0-1背包问题的最优解
在这里插入图片描述
3.计算最优值

template <class Type>
void Knapsack(Type *v, int *w, int n, Type **m)
{
	int jMax=min(w[n]-1,c);//找<w[n]的临界值,并避免物品n比背包容量还要大的情况 
	
	//最小子问题,填写最后一行m[n][j] 
	for(int j=0;j<=jMax;j++)
		m[n][j]=0;
	for(int j=w[n];j<=c;j++)
		m[n][j]=v[n];
		
	 
	for(int i=n-1;i>1;i--)
	{
		jMax=min(w[i]-1,c);
		for(int j=0;j<=jMax;j++)
			m[i][j]=m[i+1][j];//物品i装不进去
		for(int j=w[i];j<=c;j++)
			m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);//能装但不装,装进去,两个值中取较大值 
	}
	
	//填最后一行 
	m[1][c]=m[2][c];//若物品1装不进去 
	if(c>=w[1])//若物品1可以装 
		m[1][c]=max(m[2][c],m[2][c-w[1]]+v[1]); 
}
 step1:实现递归出口,填矩阵m的第n行(前3行)
 step2:循环,实现递归式,填矩阵m的第(n−1)行到第2行
 step3:填m[1][c]

4.构造最优解

template <class Type>
void Traceback(Type **m, int *w, int c, int n, int *x)//m表已经填好,已知w、c、n,输出x[],0不装,1装入
{
	for(int i=1;i<n;i++)
	{
		if(m[i][c]==m[i+1][c])
			x[i]=0;//相同则不装
		else
		{
			x[i]=1;
			c-=w[i];
		}
	}

	x[n]=(m[n][c])?1:0;		

}

第五章 回溯法

溯法有“通用的解题法”之称。
用它可以系统地搜索一个问题的所有解或任意解
它在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任一结点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对以该点为根的子树的搜索,逐层向其祖先结点回溯;否则进入该子树,继续按深度优先策略搜索。

问题的解空间

 用回溯法解问题时,应明确定义问题的解空间。
指包含解的“集合”,结构常为树或者图。
问题的解空间至少应包含问题的一个(最优)解。

0-1背包

迭代回溯

有两种方案:
第一种是保存所有子集
第二种是添加剪枝函数

3个状态:左子树、右子树、回溯
在左、右子树添加约束函数、限界函数

两种剪枝函数:
约束函数:在扩展结点处剪去不满足约束的子树;
限界函数:剪去得不到最优解的子树。

0-1背包问题(树结构)

期末考点

1.熟练求出上界的n0,C,g(N)
2.清楚Ackerman函数的代码实现
3.熟练掌握大整数相乘的p,q,r;掌握其求解过程
4.清楚大整数乘法的代码实现,尤其是递归出口
5.掌握动态规划中0-1背包的代码实现、m表、s表、及其求最优值的解
6.在动态规划中0-1背包的代码中,可能会考察代码填空,变量的各阶段的值
7.掌握备忘录代码的具体实现
8.回溯法中的旅行售货员内容 及 整本书的定义内容不会考察。

掌握的意思是必考清楚代表可能重点考察

期末在头歌上考,有代码填空及代码分析两种题型

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

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

相关文章

上海AI Lab推出8B模型,奥数成绩媲美GPT-4

只用1/200的参数&#xff0c;就能让大模型拥有和GPT-4一样的数学能力&#xff1f; 复旦大学和上海AI实验室的研究团队刚刚研发出了一款具有超强数学能力的模型。 这款模型名为MCTSr&#xff0c;以Llama 3为基础&#xff0c;参数量只有8B&#xff0c;却在奥赛级别的题目上取得了…

栈帧浅析,堆栈漏洞概述——【太原理工大学软件安全期末补充】

在上一篇文章中我说实验一不重要&#xff0c;确实没必要完全按照实验内容逐字逐句理解&#xff0c;但是这里我们补充一个知识点 栈帧&#xff08;Stack Frame&#xff09;是计算机程序执行过程中&#xff0c;调用栈&#xff08;Call Stack&#xff09;中的一个单元&#xff0c;…

C++ 64 之 函数模版和普通函数调用规则

#include <iostream> #include <string> using namespace std;template<typename T> void myPrint(T a, T b){cout << "函数模板的调用" << endl; }void myPrint(int a, int b){cout << "普通函数调用" << endl…

2.什么是计算机程序

什么是计算机程序? 计算机程序是为了告诉计算机"做某件事或解决某个问题"而用"计算机语言编写的命令集合(语句) 只要让计算机执行这个程序,计算机就会自动地、有条不紊地进行工作,计算机的一切操作都是由程序控制的,离开程序,计算机将一事无成 现实生活中你如…

【shell脚本速成】for 嵌套和和 if 高级用法

文章目录 一、for嵌套二、for与数组三、if高级用法3.1、条件符号使用双圆括号&#xff0c;可以在条件中植入数学表达式 if (())3.2、使用双方括号,可以在条件中使用通配符 四、简写if五、与文件存在与否的判断六、课后练习 &#x1f308;你好呀&#xff01;我是 山顶风景独好 &…

Jasper Studio制作报表,预览时候出现死循环,一直渲染页面,total pages无限渲染

目录 1.1、错误描述 1.2、解决方案 1.1、错误描述 最近遇到一个jasper报表线上预览出现死循环的问题&#xff0c;实施人员反馈&#xff0c;线上生产环境中&#xff0c;使用某个功能显示pdf的时候&#xff0c;出现了接口超时问题&#xff0c;在这个项目中&#xff0c;我们使用…

力扣每日一题 6/18 字符串/模拟

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;IT竞赛 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 2288.价格减免 【中等】 题目&#xff1a; 句子 是由若干个单词组成的字符…

github如何删除仓库?

之前练习Git上传的时候&#xff0c;在Github创建的测试项目已经不需要了&#xff0c;所以要如何删除&#xff1f; 首先进入Github主页&#xff0c;可以直接点击左侧1处的仓库&#xff0c;也可以点击2处的头像&#xff0c;再选择进入那个仓库。 我选择删除最后一个FlashAndShan…

YOLOv10改进 | 注意力篇 | YOLOv10引入Polarized Self-Attention注意力机制

1. Polarized Self-Attention介绍 1.1 摘要:像素级回归可能是细粒度计算机视觉任务中最常见的问题,例如估计关键点热图和分割掩模。 这些回归问题非常具有挑战性,特别是因为它们需要在低计算开销的情况下对高分辨率输入/输出的长期依赖性进行建模,以估计高度非线性的像素语…

餐饮业应该购置精酿啤酒设备吗?

近几年&#xff0c;啤酒行业刮起了一股“精酿风”&#xff0c;它不只是一种饮品口味上的变化&#xff0c;更像是一个生活方式的升级。精酿啤酒的兴起&#xff0c;不仅体现在味道的多样性和层次感上&#xff0c;更重要的是它代表了一种生活态度&#xff0c;是对品质生活的追求。…

Character Animator 2024 mac/win版:赋予角色生命,动画更传神

Character Animator 2024是一款强大的角色动画制作软件&#xff0c;以其创新的功能和卓越的性能&#xff0c;为动画师、游戏开发者以及设计师们带来了全新的创作体验。 Character Animator 2024 mac/win版获取 这款软件采用了先进的骨骼绑定技术&#xff0c;使得角色动画的制作…

充电学习—6、电量计FuelGauge

电量计功能&#xff1a; 检测电池 计量电量 电量计首要工作&#xff1a; 计算电池的剩余容量、充满时容量、电量百分比 电量百分比 剩余容量 / 充满时容量 * 100% SOC RM / FCC * 100% 典型的一个电池包框架&#xff1a; 包含电芯、电量计IC、保护IC、充放电MOSFET、保险丝…

【信息学奥赛】CSP-J/S初赛03 计算机网络与编程语言分类

第1节 计算机网络基础 1.1 网络的定义 所谓计算机网络&#xff0c;就是利用通信线路和设备&#xff0c;把分布在不同地理位置上的多台计算机连 接起来。计算机网络是现代通信技术与计算机技术相结合的产物。 网络中计算机与计算机之间的通信依靠协议进行。协议是计算机收、发…

《庆余年》在前,《玫瑰的故事》在后,阅文发现“新大陆”?

奋笔疾书的网文作家&#xff0c;即将迎来网络文学的高光时代。 近日&#xff0c;阅文集团于安徽省举办2024阅文创作大会。现场数据显示&#xff0c;2023年阅文活跃作家平均收入增长32%&#xff0c;创造近五年最大增幅。其中&#xff0c;中位数作家收入增幅达135%&#xff0c;已…

深度解析盲盒小程序APP开发过程——从设计到上线

一、引言 在上一篇文章中&#xff0c;我们为大家介绍了如何入门开发盲盒小程序APP。本文将更加深入地解析盲盒小程序APP的开发过程&#xff0c;从设计到上线全方位解析。 二、设计阶段 UI设计&#xff1a;根据目标用户群体和品牌定位&#xff0c;设计符合用户喜好和品牌风格…

鸿蒙开发网络管理:【@ohos.net.socket (Socket连接)】

Socket连接 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import socket from ohos.net.socket;socket.constructUDPSocketInstance constructUDPSocketInstance(): UDPSocket 创建…

卡本医疗VENUS登陆香港国际医疗展,探索全球医疗发展新机遇

由香港贸易发展局主办的第15届香港国际医疗及保健展、以及联合香港特别行政区政府举办的第四届亚洲医疗健康高峰论坛在中国香港圆满落幕。 香港国际医疗及保健展是亚太地区最具影响力的B2B医疗贸易展览会之一&#xff0c;辐射海内外市场&#xff0c;本次邀请了超过8500家买家以…

2024.6.18 作业 xyt

今日作业&#xff1a; 1. 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果…

5G工业路由器在智慧交通车路协同应用的深度解析

随着科技的飞速发展&#xff0c;智慧交通已成为现代城市发展的重要方向。在智慧交通的众多技术中&#xff0c;5G工业路由器凭借其高速、稳定、安全等特性&#xff0c;成为车路协同应用中不可或缺的一环。本文将在本文中深度解析5G工业路由器在智慧交通车路协同应用中的重要作用…

接口联调测试

在我们工作过程中&#xff0c;有时需要一些接口进行联调。接口联调测试&#xff0c;就是按照业务要求&#xff0c;把接口进行组合测试。接口组合起来才能实现完整的业务&#xff0c;体现更大的价值。 接口联调测试业务分析&#xff1a; 原因&#xff1a; 项目中的接口是多个…