算法设计与分析期末考试复习(三)

news2024/9/24 13:13:52

动态规划

动态规划算法与分治法类似,其基本思想也是将待求解问题分成若干个子问题。但是经分解得到的子问题往往不是互相独立的。在用分治法求解时,有些子问题被重复计算机了许多次。
如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。

与分治法的区别:

适用于动态规划算法求解的问题,经分解得到的子问题往往不是互相独立的;若用分治法求解,则分解得到的子问题数目太多,导致最终解决原问题需指数时间。
原因在于:虽然子问题的数目常常只有多项式量级,但在用分治法求解时,有些子问题被重复计算了许多次。

动态规划的基本思路:构造一张表来记录所有已解决的子问题的答案(无论算法形式如何,其填表格式是相同的)

动态规划算法的基本步骤:

  1. 找出最优解的性质(分析其结构特征)。
  2. 递归地定义最优值(优化目标函数)。
  3. 以自底向上的方式计算出最优值。
  4. 根据计算最优值时得到的信息,构造最优解。

矩阵连乘问题

标准解法,设A是pxq的矩阵,B是qxr的矩阵,数乘次数为pxqxr,算法时间复杂度为0(n3)

void matrixMultiply(int **Ma,int **Mb,int **Mc,int ra,int ca,int rb,int cb){
	if(ca!=rb)	error("矩阵不可乘");
	for(int i=0; i<ra; i++){
		for(int j=0;j<cb;j++){
			Mc[i][j] = 0;
			for(int k=0;k<ca;k++){
				Mc[i][j] += Ma[i][k] * Mb[k][j];	
			}
		}
	}
}

通过加括号的方式确定矩阵连乘问题的计算次序

  1. 单个矩阵是完全加括号的。
  2. 矩阵连乘积是完全加括号的。

在这里插入图片描述

应用动态规划,首先应分析问题的最优解结构特征,将矩阵连乘积(Ai…Aj)记为A[i][j],考虑A[1][n]的最优计算次序:

  1. 设最优计算次序在Ak和Ak+1之间将矩阵链断开。
  2. 则相应的完全加括号方式为(A1…Ak)(Ak+1…An)
  3. 总计算为以下三部分计算量之和:求解A[1:K]的计算量,求解A[k+1:n]的计算量,求解A[1:k]和A[k+1:n]相乘的计算量。

分析最优解的结构:A[1:n]的一个最优计算次序所包含的矩阵子链也是最优的,即A[1:k]和A[k+1:n]的计算次序也是最优的

建立递归关系,递归地定义最优值。

  1. 设:计算A[i:j]所需的最少数乘次数为m[i][j],则原问题的最优值为m[1][n]。
  2. 当i=j时,m[i][j]=0
  3. 当i<j时,可利用最优子结构性质来计算m[i][j],设Ai的维度为Pi-1xPi,假设A[i:j]的最优划分位置为k,则m[i][j]=m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j],k的取值只有j-i个,即k∈{i,i+1,…,j-1},k是使其中计算量达到最小的位置,因此m[i][j]可定义为:
    在这里插入图片描述

计算最优值:简单地递归
在这里插入图片描述

第四步:构造最优解对应的问题解值,需设置另一张表s:在填充表m的过程中,记录各个子链取最优值时的分隔位置k

  1. S[i][j]=k表示:A[i:j]的最优划分方式是(A[i:k])(A[k+1:j])。
  2. 从s[1][n]记录的信息可以知道A[1:n]的最优划分方式

初始化是将m[i][i],即对角线初始化为0,最顶层是m[1][n]

数据结构

  1. 形参表中应有n和P[n+1]。
  2. 算法需要两个二维数组m[n][n]。其每个元素m[i][j]为A[i:j]的最少数乘次数,二维矩阵s[n][n],其元素为断点位置。
void matrixChain(int *p,int n,int **m,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<n;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;
				}
			}
		}
	}
}

算法复杂度分析:matrixChain的主要计算量取决于算法中对r,i和k的三重循环,因此算法的计算时间上界为O(n3),算法所占用的空间为O(n2)
在这里插入图片描述

动态规划算法的基本要素

最优子结构
矩阵连乘的计算次序问题具有最优子结构性质——矩阵连乘计算次序问题的最优解包含着其子问题的最优解。
在分析问题的最优子结构性质,所用的方法具有普遍性:

  1. 首先假设由问题的最优解导出的子问题的解不是最优的
  2. 然后设法证明在该假设下可构造出比原问题最优解更好的解
  3. 通过矛盾法证明由最优解导出的子问题的解也是最优的

解题方法:利用问题的最优子结构性质,以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解。

最优子结构是问题能用动态规划算法求解的前提,同一个问题可以有多种方式刻画它的最优子结构,有些表示方法的求解速度更快。(空间占用小,问题的维度低)

重叠子问题
采用递归算法求解问题时,产生的子问题并不总是独立的。有些子问题被反复计算多次,称为子问题的重叠性质。

备忘录方法

备忘录方法是动态规划算法的一种变形,它也用表格来保存已解决的子问题答案,以避免重复计算。

与动态规划的区别在于备忘录方法是自顶向下的递归。

备忘录方法的控制结构与直接递归方法的控制结构相同。

  • 区别在于备忘录方法为每个解过的子问题建立了备忘录。
  • 以备需要时查看,从而避免了相同子问题的重复求解。

算法时间复杂度O(n3),算法空间复杂度为O(n2)。

int MemorizedMatrixChain(int n,int **m,int **s){
	for(int i=1; i<=n; i++)
		for(int j=i; j<=n; j++)
			m[i][j] = 0;
	return LookupChain(1,n);
}

int LookupChain(int i,int j){
	if(m[i][j] > 0)	return m[i][j];
	if(i == j)
		return 0;
	int u = LookupChain(i,i) + LookupChain(i+1,j) + p[i-1]*p[i]*p[j];
	s[i][j] = i;
	for(int k=i+1; k<j; k++){
		int t = LookupChain(i,k) + LookupChain(k+1,j) + p[i-1]*p[k]*p[j];
		if(t < u){
			u = t;
			s[i][j] = k;
		}
	}
	m[i][j] = u;
	return u;
}

最长公共子序列问题(Longest Common Subsequence)

子序列和子串
在这里插入图片描述
最长公共子序列问题具有最优子结构性质
给定序列X={x1, x2, ……, xm} 和 Y={y1, y2, ……, yn},设它们的一个最长公共子序列为Z={z1, z2,…, zk} ,则:

  1. 若xm = yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的LCS
  2. 若xm!=yn且zk!=xm,则Z是Xm-1和Y的LCS
  3. 若xm!=yn且zk!=yn,则Z是X和Yn-1的LCS

可见LCS(X,Y)包含了X和Y这2个序列的前缀子序列的LCS,因此最长公共子序列问题具有最优子结构性质。

假如S1的最后一个元素与S2的最后一个元素不相等,那么S1和S2的最长公共子序列等于:{S1减去最后一个元素}与S2的最长公共子序列,{S2减去最后一个元素}与S1的LCS中的最大的那个序列。

建立递归关系,用c[i][j]表示序列Xi和Yj的最长公共子序列的长度。
在这里插入图片描述
如果直接用递归算法求解递归式,则时间随输入规模成指数增长。

设置两个数组作为输出:

  1. c[i][j]表示序列Xi和Yj的最长公共子序列的长度,问题的最优值记为c[m][n],即LCS(X,Y)的长度。
  2. b[i][j]记录c[i][j]是从哪一个子问题的解得到的,数组b用于构造最长公共子序列(最优解)。
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(j=1; 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;
				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;
			}
		}
	}
}

算法时间复杂度O(mn)
在这里插入图片描述
在这里插入图片描述
构造最长公共子序列

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);
	}
}

还可以去掉数组b,只需要根据c[i][j]和每个字符串最后字符是否相等判断。

最大子段和问题(Maximum Sub-Sequence Sum)

给定n个整数(可能为负数)组成的序列a1,a2,…,an,求该序列形如下式的子段和的最大值,当所有整数均为负整数时定义其最大子段和为0。

最大子段和问题:简单算法,时间复杂度O(n2)

int MaxSum(int n,int *pa,int *besti,int *bestj){
	int sum = 0;
	for(int i=1; i<=n; i++){
		int tmp =0;
		for(int j=i; j<=n; j++){
			tmp +=pa[j];
			if(tmp > sum){
				sum = tmp;
				*besti = i;
				*bestj = j;
			}
		}
	}
}

最大子段和问题:分治算法,时间复杂度O(nlogn)

  1. 如果将序列a[1:n]分为等长两段:a[1:n/2]和a[n/2+1:n]
  2. 可以分别求出a[1:n/2]和a[n/2+1:n]的最大子段和
  3. 原问题的最大子段和a[1:n]有三种情形:a[1:n]的最大子段和与a[1:n/2]的最大子段相同,a[1:n]的最大子段和与a[n/2+:n]的最大子段相同,a[1:n]的最大子段和产生于跨越两段分界点的子序列——显然此时有a[n/2]和a[n/2+1]在最优子序列中,可分别求得包含a[n/2]和a[n/2+1]的极大子段和S1和S2,则a[1:n]的最大子段和=S1+S2。
int MaxSubSum(int *a,int left,int right){
	int sum = 0;
	if(left == right)	sum=a[left]>0 ? A[left]:0;
	else{
		int center = (left+right)/2;
		int leftSum = MaxSubSum(a,left,center);
		int rightSum = MaxSubSum(a,center+1,right);
		
		//从中向左
		int s1 = 0;
		int lefts = 0;
		for(int i=center; i>=left;i--){
			lefts+=a[i];
			if(lefts > s1){
				s1 = lefts;
			}
		}

		int s2 = 0;
		int rights = 0;
		for(i=center+1; i<=right;i++){
			rights += a[i];
			if(rights > s2){
				s2 = rights;
			}
		}
		sum = s1+s2;
		if(sum < leftSum){
			sum = leftSum;
		}
		if(sum < rightSum){
			sum = rightSum;
		}
	}
	return sum;
}

最大子段和问题:动态规划算法时间复杂度O(n)

int MaxSum(int n,int *a){
	int sum = 0;
	int b = 0;
	for(int i=1; i<=n; i++){
		if(b>0){
			b+=a[i];
		}else{
			b = a[i];
		}
		if(b > sum){
			sum = b;
		}
	}
	return sum;
}

凸多边形最优三角剖分问题

当一个简单多边形及其内部构成一个闭凸集时,称为凸多边形。
凸集的含义:凸多边形边界或内部的任意两点所连成的直线段上的所有点均在凸多边形的内部或边界上。
通常用多边形顶点的逆时针序列表示凸多边形,V={v0, v1, ……, vn-1} 表示具有n条边(v0, v1),(v1, v2 ),……,(vn-1 , vn)的一个凸多边形(约定:v0 =vn )。

凸多边形的三角剖分

  1. 将多边形P分割成互不相交的三角形的弦的集合T。
  2. 在该部分中各弦互不相交,且集合T已达到最大。

在有n个顶点的凸多边形,恰有n-3条弦和n-2个三角形。

给定凸多边形P,以及定在由多边形的边和弦组成的三角形上的权函数W,要求确定该凸多边形的三角部分,使得该三角部分中诸三角形上权值之和最小。

完全加括号表达式的语法树
矩阵连乘的最优计算次序等价于矩阵链的最优完全加括号方式,一个表达式的完全加括号方式相当于一颗平衡二叉树

例如:完全加括号的矩阵连乘积((A1(A2A3))(A4(A5A6))),可以用如下的平衡二叉树进行表示,其中叶节点为表达式中的原子;树根表示左右子树相结合,这样的二叉树称为该表达式的语法树。

在这里插入图片描述
凸多边形三角剖分也可以用语法树来表示(如图)
在这里插入图片描述

  1. 该语法树的根节点为边(V0,V6)
  2. 三角剖分中的弦组成其余的内节点(子树的根节点)
  3. 多边形中除(V0,V6)外的各条边都是语法树的一个叶节点。

凸多边形三角剖分与矩阵连乘问题的同构关系

  1. 凸n边形的三角剖分和有n-1个叶节点的语法树存在一一对应关系。
  2. n个矩阵的完全加括号乘积和有n个叶节点的语法树存在一一对应关系。
  3. 推论:n个矩阵连乘的完全加括号和凸n+1边形的三角剖分也存在一一对应关系。其中Ai对应于凸多边形的一条边(Vi-1,Vi),三角剖分中的每条弦(Vi,Vj)对应于一组矩阵的连乘积A[i+1,j]

矩阵连乘的最优计算次序问题是凸多边形最优三角剖分的特例。

  1. 对于给定的矩阵链(A1 A2 … An)。
  2. 定义一个与之相应的凸多边形P={v0,v1,…,vn}。
  3. 使得矩阵Ai与凸多边形的边(Vi-1,Vi)一一对应。
  4. 若矩阵Ai的维数为Pi-1xPi
  5. 定义三角形(ViVjVk)上的权函数值:w(ViVjVk)=pixpjxpk
  6. 则凸多边形P的最优三角剖分所对应的语法树同时也给出了该矩阵A1A2 … An 的最优完全加括号方式

凸多边形最优三角剖分的最优子结构性质
设:T为凸多边形P={v0,v1,…,vn}的一个最优三角剖分。
并设:T包含三角形v0vkvn
则:T的权为三部分权之和:三角形v0vkvn的权,以及两个子多边形{V0,…,Vk}和{Vk,…,Vn}的权之和。
可以断言:由T所确定的这两个子多边形的三角剖分也是最优的。
这是因为:若子多边形有更小权的三角剖分,则三部分之和将小于T的值,这将导致T不是最优三角剖分的矛盾。
设:t[i][j]为凸子多边形p{Vi-1,Vi,…,Vj}的最优三角剖分所对应的权函数值,即三角剖分的最优值。
设:退化的两顶点多边形{Vi-1Vi}具有权值0(t[i][i] = 0)
则:原问题(凸n+1边形)的最优权值为t[1][n]。
当(j-i)>=1时,凸子多边形{Vi-1,Vi,…,Vj}至少有三个顶点,设k为其中一个中间点(i<=k<j),由最优子结构性质,t[i][j]的值应为三部分权值之和:两个凸子多边形的最优权值t[i][k]和t[k+1][j]加上三角形Vi-1VkVj的权值。
由于K的可能位置有j-i个,因此问题转换为:在其中选择使得t[i][j]达到最小的位置,相应地得到t[i][j]递归定义如下:
在这里插入图片描述
与矩阵连乘问题相比,除了权函数的定义外,t[i][j]与m[i][j]的递归式完全相同,因此只需对MatrixChain算法做少量修改即可。
在这里插入图片描述

void minweighttriangulation(int n,int **t,int **s){
	for(int i=1; i<=n; i++)	t[i][i] = 0;
	for(int r=2; r<=n; r++){
		for(int i=1; i<=n-r+1; i++){
			int j = i+r-1;
			t[i][j] = t[i+1][j] + w(i-1,i,j);
			s[i][j] = i;
			for(int k=i+1; k<n; k++){
				int u = t[i][k] + t[k+1][j] + w(i-1,k,j);
				if(u < t[i][j]){
					t[i][j] = u;
					s[i][j] = k;
				}
			}
		}
	}
}

与矩阵连乘算法的复杂度一样,计算时间上界为O(n3),算法所占用的空间为O(n2)。

凸多边形最优三角剖分的最优解

  • 计算最优值t[1][n]时,可以用数组S记录三角剖分信息。
  • S[i][j]记录于(Vi-1,Vj)共同组成三角形的第三个顶点的位置。

图像压缩问题

灰度图
灰度图是指用灰度表示的图像,灰度是在白色和黑色之间分的若干个等级,其中最常用的是256级,也就是256级灰度图,灰度就是没有色彩,RGB色彩分量全部相等。
例如:RGB(100,100,100) 代表灰度为100
例如:RGB(50,50,50) 代表灰度为50
在计算机中常用像素点的灰度值序列来表示图像

**灰度图的压缩:**图像A的像素点灰度值序列为:{p1,p2,…pn},整数值pi (0 ≤ pi ≤ n) 表示像素点 i 的灰度值,像素点灰度值取值范围[0-255],表示为8位二进制数,减少表示像素点的位数,可以降低图像的空间占用需求。

设:P = {10,12,15,255,1,2,1,1,2,2,1,1}

  1. S1 = {10, 12, 15, 255, 1, 2, 1, 1, 2, 2, 1, 1}
  2. 分成12个组,每组仅包含一个像素
  3. S1 = {10, 12, 15} S2 = {255} S3 = {1, 2, 1, 1, 2, 2, 1, 1}

所需存储空间
分法1:8×12 + 11×1 = 107
分法2:4×3 + 8×1 + 1×5 + 2×3 + 11×12 = 163
分法3:4×3 + 8×1 + 2×8 + 11×3 = 69

0/1背包问题

证明0/1背包是最优子结构(反证)
设(x1,x2,…,xn)是所给0/1背包问题的一个最优解,则(x2,…,xn)是下面一个子问题的最优解:
在这里插入图片描述
如若不然,设(y2,…,yn)是上述问题的一个最优解,则
在这里插入图片描述
这说明(x1,y2,…,yn)是所给0/1背包问题比(x1,x2,…,xn)更优的解,从而导致矛盾。

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

  • 把前面i个物品装入容量为0的背包和把0个物品装入容量为j的背包,得到的价值均为0。
  • 如果第i个物品的重量大于背包的容量,则物品i不能装入背包,则装入前i个物品得到的最大价值和装入前i-1个物品得到的最大价值是相同的。
  • 如果第i个物品的重量小于背包的容量,就会有两种情况:如果第i个物品没有装入背包,则背包中物品的价值就等于前i-1个物品装入容量为j的背包中所取得的价值。
  • 如果第i个物品装入背包,则背包中物品的价值等于前i-1个物品装入容量为j-w[i]的背包中的价值加上第i个物品的价值vi。
  • 取二者中价值较大者作为前i个物品装入容量为j的背包中的最优解。

设n个物品的重量存储在数组w[n]中,价值存储在v[n]中,背包容量C,数组V[n+1][C+1]存放迭代结果,其中V[i][j]表示前i个物品装入容量为j的背包中获得的最大价值,数组x[n]存储装入背包的物品,动态规划法求解0/1背包问题:

int KnapSack(int n,int w[],int v[]){
	for(int i=0; i<=n; i++)
		V[i][0] = 0;
	for(int i=0; i<=C; i++)
		V[0][i] = 0;
	for(int i=1; i<=n; i++){
		for(int j=1; j<=C; j++){
			if(w[i] > j){
				V[i][j] = V[i-1][j];
			}else{
				if(V[i-1][j-w[i]]+v[i] >= V[i-1][j]){
					V[i][j] = V[i-1][j-w[i]] + v[i];
				}else{
					V[i][j] = V[i-1][j];
				}
			}
		}
	}
	// 求装入背包的物品
	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];
}

算法时间复杂度为O(nxC)

最优二叉查找树(Optimal Binary Search Tree)

二叉查找树

  • 设S={k1,k2,…,kn}是n个互异的关键字组成的有序集,且k1<k2<…<kn。
  • 可利用二叉树的节点存储有序集S中的元素,称为二叉查找树。

二叉查找树的性质

  • 二叉查找树中任意节点:大于其左子树中任意节点;小于等于其右子树中任意节点。
  • 二叉查找树的叶节点是形如(ki,ki+1)的开区间,以符号di表示虚拟的叶节点,约定d0=-无穷,dn+1=正无穷
  • 在二叉查找树中搜索一个元素k,返回的结果有两种情况,在二叉查找树的内节点中找到ki==k,在二叉查找树的叶节点中确定k ∈ (ki, ki+1)

二叉搜索树的搜索代价:已知了每个关键字和虚拟键被搜索的概率,可以确定在给定二叉搜索树T内一次搜索的期望代价。假设一次搜索的实际代价为检查的结点的个数,在T内搜索所发现的“结点的深度”加“1”。

在这里插入图片描述
k3的结点深度为3,要找到结点k3,需要检查3+1=4个结点的个数k2 k5 k4 k3。
在这里插入图片描述
证明最优二叉查找树满足最优性原理
将由{r1,r2,…,rn}构成的二叉查找树记为T(1,n),其中rk(1≤k≤n)是T(1,n)的根节点,则其左子树T(1,k-1)由{r1,…,rk-1}构成,其右子树T(k+1,n)由{rk+1,…,rn}构成。

若T(1,n)是最优二叉查找树,则其左子树T(1,k-1)和右子树T(k+1,n)也是最优二叉查找树,如若不然,假设S(1,k-1)是比T(1,k-1)更优的二叉查找树,则S(1,k-1)的平均比较次数小于T(1,k-1)的平均比较次数,从而由S(1,k-1),rk,T(k+1,n)构成的二叉查找树S(1,n)的平均比较次数小于T(1,n)的平均比较次数,这与T(1,n)是最优二叉查找树的假设矛盾。

最优子结构分析
对于给定关键字序列{ki,…,kj},假设kr是包含该序列的一棵最优子树的根,根kr的左子树包含ki,…kr-1,根kr的右子树包含kr+1,…kj。

  • 依次检查所有的侯选根(设为kr)。
  • 确定包含关键字ki,…kr-1和kr+1,…,kj的所有二叉查找树。
  • 其中期望搜索代价最小就是最优二叉查找树。
  • 问题的关键:确认“权重”函数(子树的期望代价)

钢条切割问题

某公司出售一段长度为i英寸的钢条的价格为p[i](i=1,2,3,…),钢条长度整英寸如图:
在这里插入图片描述
现在先给一段长度为n的钢条,问怎么切割,获得的收益最大rn?
在这里插入图片描述
假如一个最优解把n段切成了k段(1≤k≤n),那么最优切割方案:n=i[1]+i[2]+…+i[k],最大收益:rn=p[i[1]]+p[i[2]]
在这里插入图片描述
第一个参数Pn为不切割方案,其它n-1个参数对应n-1种方案:对于每个i=1,2,…,n-1,首先把钢条分为长度为i和n-i的两端钢条,分别求出这两段钢条的最优ri和rn-i(每种方案的最优收益为两段的最优收益之和)。

生产与存储问题

某工厂每月需供应市场一定数量的产品。供应需求所剩余产品应存入仓库,一般地说,某月适当增加产量可降低生产成本,但超产部分存入仓库会增加库存费用,要确定一个每月的生产计划,在满足需求条件下,使一年的生产与存储费用之和最小。

投资决策问题

某公司现有资金Q亿元,在今后5年内考虑给A、B、C、D四个项目投资,这些项目的投资期限、回报率均不相同,问应如何确定这些项目每年的投资额,使到第五年末拥有资金的本利总额最大。

设备更新问题

企业使用设备都要考虑设备的更新问题,因为设备越陈旧所需的维修费用越多,但购买新设备则要一次性支出较大的费用。现在某企业要决定一台设备未来8年的更新计划,已预测到第j年购买设备的价格为Kj,Gj为设备经过j年后的残值,Cj为设备连续使用j-1年后在第j年的维修费用(j=1,2…8),问应在哪年更新设备可使总费用最小

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

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

相关文章

Scala-抽象类、匿名子类、伴生对象、单例模式

抽象类 匿名子类 伴生对象&#xff08;单例对象&#xff09; 单例设计模式 抽象类 定义抽象类&#xff1a;abstract class Person{} //通过 abstract 关键字标记抽象类定义抽象属性&#xff1a;val|var name:String //一个属性没有初始化&#xff0c;就是抽象属性定义抽象…

应用场景六:同时支持CP343和CP341功能(Modbus连接仪表,以太网连接WINCC)

应用描述&#xff1a; 桥接器同时支持西门子PLC的CP343以太网通讯模块和CP341串口通讯模块的功能。可以同时通过ModbusRTU连接仪表、变频器等串口设备&#xff0c;同时可以通过网口连接组态监控软件WINCC。PLC内部不需要编程&#xff0c;也不需要进行硬件组态配置&#xff0c;…

FME+YOLOV7写DNF自动刷图脚本

目录 前言 一、难点分析 二、实现流程 1.DNF窗口位置获取 2.获取训练数据 3.数据标注 4.数据格式转换 5.数据训练 5.刷图逻辑编写 前言 这是一篇不务正业的研究&#xff0c;首先说明&#xff0c;这不是外挂&#xff01;这不是外挂&#xff01;这不是外挂&#xff01;这只是用a…

【网络原理10】构造HTTP请求、HTTPS加密

目录 一、构造HTTP请求 ①使用form表单构造HTTP请求&#xff1a; form表单是如何提交的 form提交的缺点 ②基于ajax构造http请求 如何使用Jquery框架 二、HTTPS 运营商劫持 HTTP的加密版本&#xff1a;HTTPS ①对称加密&#xff1a;客户端和服务端使用同一把密钥&…

【AcWing】差分及其应用

&#x1f386;音乐分享 光辉岁月 (粤语版)_BEYOND 所谓差分&#xff0c;就是前缀和的逆运算 &#xff08;不懂前缀和的同学可以去C站看一下&#x1f602;&#xff09; 797. 差分 - AcWing题库 代码 #include<iostream> using namespace std; const int N 1e5 10…

怎样选择运动耳机、5款最佳运动蓝牙耳机推荐

你是否在跑步时大幅度抖动让耳机松落&#xff0c;不得不一遍又一遍的塞紧耳机&#xff1f;你是否在游泳时因为耳机进水而懊恼自己大意&#xff1f;没错&#xff0c;在运动过程中这些情况我都有遇到过&#xff01;运动耳机因其使用都是在跑步、游泳、骑行、徒步等场景&#xff0…

Apache Hadoop生态部署-Maxwell(实时数据同步)采集节点安装

目录 Apache Hadoop生态-目录汇总-持续更新 1&#xff1a;安装包准备 2&#xff1a;MySQL 环境准备 2.1&#xff1a;开启MySQL Binlog 2.2&#xff1a;验证mysql配置是否正确 2.3&#xff1a;初始化Maxwell元数据库,分配账号 3&#xff1a;安装 4&#xff1a;测试 Apach…

【开发规范】go项目开发中的[流程,git,代码,目录,微服务仓库管理,静态检查]

文章目录前言一、有哪些规范我们应该遵循二、项目开发流程三、git的代码分支管理1. 分支管理2. commit规范三、go的代码规范四、go项目目录规范五、微服务该采用multi-repo还是mono-repo&#xff1f;1. 引言2. Repos 是什么?3. 什么是 Mono-repo?4. Mono-repo 的劣势5. 什么是…

1、算法导论---时间复杂度、确定性和非确定性图灵机、算法的确定性与非确定性、P问题、NP问题、规约/约化、NPC问题、NP-hard问题

算法导论1、 时间复杂度2、图灵机3、算法的确定性与非确定性4、P问题5、NP问题6、规约/约化7、NPC问题8、NP-Hard问题9、四大问题关系1、 时间复杂度 要想了解算法的问题&#xff0c;首先要知道问题的分类&#xff0c;而要想知道问题的分类&#xff0c;就要先了解时间复杂度。…

_vue-2

v-model实现原理 我们在 vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定&#xff0c;我们知道 v-model 本质上不过是语法糖&#xff08;可以看成是value input方法的语法糖&#xff09;&#xff0c;v-model 在内部为不同的输入元素…

什么是原型、原型链?原型和原型链的作用

1、ES6之前&#xff0c;继承都用构造函数来实现&#xff1b;对象的继承,先申明一个对象&#xff0c;里面添加实例成员<!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title></head><body><script…

Ubuntu(虚拟机)的Anaconda 及使用

安装Anaconda 使用firefox打开Ananconda网址Anaconda | The Worlds Most Popular Data Science Platform 下载后有.sh文件&#xff1a; Anaconda3-2022.10-Linux-x86_64.sh 进入所在目录打开终端并输入 $ bash Anaconda3-2022.10-Linux-x86_64.sh 然后开始安装。 对于给…

SAP MM学习笔记1-SAP中扩张的概念,如何将一个物料从工厂A扩张到工厂B

MM中在创建物料的时候&#xff0c;最低也得创建如下5个view。 基本数据1 基本数据2 购买管理 会计1 会计2 1&#xff0c;扩张是什么 有时候&#xff0c;你想增加其他的View&#xff0c;比如保管场所 等&#xff0c;你不能用MM02来做编辑&#xff0c;要用MM01来做扩张。这就是扩…

OSPF的多区域特性 (电子科技大学TCP/IP实验三)

一&#xff0e;实验目的 1、掌握OSPF 协议中区域的类型、特征和作用 2、掌握OSPF 路由器的类型、特征和作用 3、掌握OSPF LSA 分组的类型、特征和作用 4、理解OSPF 区域类型、路由器类型和OSPF LSA 分组类型间的相互关系 二&#xff0e;预备知识 1、静态路由选择和动态路…

分享美容美发会员管理系统功能的特点_美容美发会员管理系统怎么做

人们越来越关心美发&#xff0c;美发行业发展迅速&#xff0c;小程序可以连接在线场景&#xff0c;许多美发院也开发了会员卡管理系统。那么一个实用的美发会员管理系统怎么制作呢&#xff1f;它有什么功能&#xff1f;我们一起来看看~&#xff08;干货满满&#xff0c;耐心看完…

Lenovo Legion Y530-15ICH电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。硬件型号驱动情况主板Lenovo Legion Y530-15ICH处理器Intel Core™ i7-8750H (Coffee-Lake)已驱动内存16GB RAM DDR4 2667MHz已驱动硬盘2TB HP EX950 PCI-E Gen3 x4 NVMe SSD已驱动显卡Intel UHD Graphics 630Nvidia GTX 10…

电子科技大学TCP/IP实验一——IP分组和ARP协议

目录 一&#xff0e;实验目的 二&#xff0e;预备知识 三&#xff0e;实验原理 四&#xff0e;实验内容 五&#xff0e;实验步骤 六、实验数据及结果分析 七、实验结论 八、总结及心得体会 九、对本实验过程及方法、手段的改进建议 一&#xff0e;实验目的 1、掌握 IP…

Lambda表达式的本质

一直想写一篇文章&#xff0c;来总结lambda表达式&#xff0c;但是之前感觉总结的不是特别到位&#xff0c;现在看了几篇文章和视频后&#xff0c;感觉对lambda表达式有了比较深刻的认识&#xff0c;现在进行记录总结如下&#xff1a; lambda表达式又叫做匿名函数&#xff0c;…

数据恢复软件EasyRecovery Photo16新版本功能特点介绍

EasyRecovery Photo16是一款支持Mac/Wind平台进行恢复图片的专业工具&#xff0c;尤其是各种流行单反相机RAW格式文件&#xff0c;以及超大型视频文件等&#xff0c;摄影爱好者使用。EasyRecovery是一款非常专业的硬盘数据恢复工具&#xff0c;可以帮你恢复丢失的数据&#xff…

【论文极速读】VQ-VAE:一种稀疏表征学习方法

【论文极速读】VQ-VAE&#xff1a;一种稀疏表征学习方法 FesianXu 20221208 at Baidu Search Team 前言 最近有需求对特征进行稀疏编码&#xff0c;看到一篇论文VQ-VAE&#xff0c;简单进行笔记下。如有谬误请联系指出&#xff0c;本文遵循 CC 4.0 BY-SA 版权协议&#xff0c;…