HNU算法设计与分析期末(2025年信安)

++都是我自己的答案,不一定正确,仅供参考++

1.A:和B:,这两个分别表示什么,哪个价值更高,为什么?

前一个表示渐进上界,后一个表示渐进下界

我写的前一个价值更高,因为我们更习惯考虑时间开销的上限来判断一个算法的可行性(前一个使用多一点)

2.分治法和动态规划的异同?为什么有些不能使用动规但是能使用分治?

我是这么回答的:

相同:都需要分解成子问题,都可以用来解决最优问题;

异:分治法的子问题相互独立互不重叠,动规的子问题有重叠;分治法自上而下递归,需要合并子问题,而动规自底向上计算,不需要合并子问题:分治法分治法不存储子问题的解,动规需要存储子问题。

为什么有些不能用动规可以用分治:因为有些问题不具备最优子结构和重叠子问题;或者有些问题不需要求最优解,这时候使用分治法

3.限界函数为什么重要?好的限界函数应该具备什么性质?

我的回答:

如果没有限界函数,往往需要遍历所有解空间数,可能达到指数或者阶乘级别,因此需要使用限界函数避免一些无效的搜索,减少时间开销。

性质:1.需要能够快速排除较多的无效探索,2.计算开销不能过大,否则会导致时间开销更多

4.使用分治法求解数组的最大连续和问题

这题最佳方法是动态规划,但是题目要求使用分治,我的写法:

首先可以分成三个部分:左,右,跨越左右

左右都可以直接使用递归实现

跨越左右的部分我是采用了双指针贪心法:先固定左指针在左边最右的位置,右指针在右边最左的位置,每次比较左右较大值,较大的一方加入sum,然后将指针朝边缘移动,并且比较sum和cross_max,使得cross_max最大。

最终返回max(left_max,right_max,cross_max)

5.给定一个m×n的二维数组grid,每个元素都是一个数字,然后计算从(0,0)到(m-1,n-1)的最小值(每次只能向右和向下,路过的位置加入到sum中)

这题是经典的动态规划,可以列出状态转移方程:

6.一辆车从起点出发,每次加油后可以行驶k公里,每两个加油站的距离保存在x数组中,问最少要加多少次油

贪心算法,每次直到油不够跑到下一个加油站的时候才加油

7.给定一个m×n的二维字符数组board,给定目标word(一维数组),要求从board中选择一个起点,每次可以朝周围四个方向选择,要求最终能按word的顺序遍历,并且不能重复使用已经使用的字符(位置)

使用回溯法,我的思路如下(给出伪代码):

cpp 复制代码
bool backtrace(char **board,char *word,int n,int m,int i ,int j,int k,bool *visit){
	if(k == word.size()) return true;
	int grid = {{1,0},{-1,0},{0,-1},{0,1}};
	for(int d = 0; d < 4; d++){
		ni = i + grid[d][0];
		nj = j + grid[d][1];
		if(ni < 0 || ni >=n || nj < 0 || nj >= m) continue;
		if(board[ni][nj] == word[k] && !visit[ni][nj]){
			k++;
			visit[ni][nj] = true;
			if(backtrace(board,word,n,m,ni,nj,k,visit)) return true;
			visit[ni][nj] = false;
			k--;
		}
	}
	return false;
} 

int main(){
	for(int i = 0; i < n; i ++){
		for(int j = 0; j < m; j++){
			backtrace(board,word,n,m,i,j,0,visit);
		}
	}
}

8.给定n个工人和n个任务,和costnn表示第i个工人干第j个任务的开销,使用分支限界法使得开销最少

这题可以使用优先队列的分支限界法,我在做的时候没有给出完整逻辑,大致逻辑如下:

定义一个最小堆min_heap,按照当前已经耗费+剩下工人每个人选剩下的最小耗费来进行比较,第一个完成分配的就是最终的结果。

在遍历时由于是排列,可以采取swap进行遍历,但是我在写的时候由于min_heap里面我设计了最小耗费和当前安排的工作数量,我加上了安排了工人vector<int> people,所以遍历时我使用find查看当前工人是否已经在people中来遍历。

给出伪代码:

cpp 复制代码
int BFS(int **cost,int n){
	min_heap<node> prior_q;
	for(int i = 0; i < n; i++){
		prior_q.push(node(cost[i][0]+last,1,i));//分别是累计开销,下一个执行任务,当前的工人 
	}
	while(!prior_q.empty()){
		curr_node = prior_q.front();
		prior_q.pop();
		if(curr_node.t == n) return curr_node.cost;
		for(int i = 0; i < n; i++){
			if(!curr_node.find(i)){
				prior_q.push(node(cost[i][t]+last,t+1,i));
			}
		}
	} 
}
相关推荐
明月_清风3 小时前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
渡我白衣3 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
hetao17338373 小时前
2026-09-01~09-04 hetao1733837 的刷题记录
c++·算法
Evand J4 小时前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动
血小板要健康4 小时前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a187927218314 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
HugoStudio_SWAN6 小时前
洛谷 P1420 / P1179 / B4262 最长连号、数字统计与词频统计——统计的三种面孔
c++·学习·程序人生·算法
青 春 记 忆7 小时前
LeetCode 350. 两个数组的交集 II|Python 解法详解
python·算法·leetcode
阳明山水8 小时前
销量预测2025—2026:从模型竞赛到系统融合的范式转型
人工智能·深度学习·算法·机器学习·架构
桐盛科技8 小时前
拒绝“漂绿”风险:基于边缘计算的碳排放数据清洗算法与实时校验逻辑
人工智能·算法·边缘计算