算法分析资料报告与设计-课程设计资料报告材料
算法设计与分析课程报告
算法设计与分析课程报告第一章算法问题求解基础1、算法的概念:算法是指解决问题的一种方法或过程,是由若干条指令组成的有穷序列。
2、算法的特性①有穷性:一个算法必须保证执行有限步之后结束;②确切性:算法的每一步骤必须有确切的定义;③输入:一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定除了初始条件;④输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果。
没有输出的算法是毫无意义的;⑤可行性:算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成3、算法与程序的关系:区别:程序可以不一定满足可终止性。
但算法必须在有限时间内结束;程序可以没有输出,而算法则必须有输出;算法是面向问题求解的过程描述,程序则是算法的实现。
联系:程序是算法用某种程序设计语言的具体实现;程序可以不满足算法的有限性性质。
4、算法描述方式:自然语言,流程图,伪代码,高级语言。
第二章算法分析基础1、算法复杂性分析:算法复杂性的高低体现运行该算法所需计算机资源(时间,空间)的多少。
算法复杂性度量:期望反映算法本身性能,与环境无关。
理论上不能用算法在机器上真正的运行开销作为标准(硬件性能、代码质量影响)。
一般是针对问题选择基本运算和基本存储单位,用算法针对基本运算与基本存储单位的开销作为标准。
算法复杂性C依赖于问题规模N、算法输入I和算法本身A。
即C=F(N, I, A)。
第五章分治法1、递归算法:直接或间接地调用自身的算法。
用函数自身给出定义的函数称为递归函数。
注:边界条件与递归方程是递归函数的二个要素。
实例:①阶乘函数;②Fibonacci数列;③Ackerman函数;④排列问题;⑤整数划分问题;⑥Hanoi塔问题优缺点:①优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。
②缺点:递归算法的运行效率低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。
算法与分析报告课程设计—独立钻石跳棋问题
算法与分析课程设计报告题目:专业:班级:学号:姓名:年月日一、算法问题描述独立钻石跳棋问题。
在33个方格顶点摆放着32枚棋子,仅中间的顶点空着未摆放着棋子。
下棋的规则是任意棋子可以沿着水平或着垂直方向跳过与其相邻的棋子,进入空着的顶点并吃掉被跳过的棋子。
试设计一个算法并找出一种下棋的方法,使得棋盘上最终只剩下一个棋子在棋盘的正中央。
二、算法问题形式化表示在33个方格顶点摆放着32枚棋子,仅中间的顶点空着未摆放着棋子。
算法解决了在32个棋子摆放在有33格的盘上(只有中心格空着)在规定当一个棋子跳过邻近的一个棋子到空格时,就将这张邻近的棋子从盘上拿掉,使除了最后留在中心格一个棋子外其余的棋子均被拿掉的问题!三、期望输入与输出期望输入:显示一个棋盘,在33个方格顶点摆放着32枚棋子,仅中间的顶点空着未摆放着棋子。
期望输出:使得棋盘上最终只剩下一个棋子在棋盘的正中央四、算法分析与步骤描述总体一个回溯的思想,如果两个子字间能跳,那么我们就跳了之后记录其新的位置,因为跳的前后都是一个问题,所以我们能用递归分治,跳了一次之后棋子数减1,并把被跳过的棋子和编号最后的棋子交换,这样就达到了把棋子去掉的目的。
并把最优解保存。
如果temp当前走的次数已经大于最优解,那么我们就不用算了。
五、问题实例及算法运算步骤此次问题主要用回溯算法,基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。
在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。
算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。
如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。
否则,进入该子树,继续按深度优先的策略进行搜索。
回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。
而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。
六、算法运行截图开始时:结束后:七、附录代码(java)package sfdesign;import java.awt.Color;import java.awt.GridLayout;import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class DC extends JFrame {//-----move时候用的变量们public static int oldx = 0;public static int oldy = 0;public static int newx = 0;public static int newy = 0;public static boolean movingflag = false;//-----layeroutprivate GridLayout gamepanellayer = new GridLayout(1, 2); private GridLayout optionlayer = new GridLayout(2, 1); private GridLayout chessboardlayer = new GridLayout(9, 9); //-----左右布局的jpanelprivate JPanel leftpanel = new JPanel();private JPanel rightpanel = new JPanel();//-----public static int restcount = 32;public static int steps = 0;public static JLabel jl1 = new JLabel("剩余子数:" + restcount); public static JLabel jl2 = new JLabel("当前步数:0" + steps); //-----board点阵public static boolean[][] chessboard = {{false, false, false, false, false, false, false, false, false}, {false, false, false, true, true, true, false, false, false}, {false, false, false, true, true, true, false, false, false}, {false, true, true, true, true, true, true, true, false}, {false, true, true, true, true, true, true, true, false}, {false, true, true, true, true, true, true, true, false}, {false, false, false, true, true, true, false, false, false}, {false, false, false, true, true, true, false, false, false}, {false, false, false, false, false, false, false, false, false} };//-----chess点阵public static boolean[][] chessdot = {{false, false, false, false, false, false, false, false, false}, {false, false, false, true, true, true, false, false, false}, {false, false, false, true, true, true, false, false, false}, {false, true, true, true, true, true, true, true, false}, {false, true, true, true, false, true, true, true, false}, {false, true, true, true, true, true, true, true, false}, {false, false, false, true, true, true, false, false, false}, {false, false, false, true, true, true, false, false, false}, {false, false, false, false, false, false, false, false, false} };//-----chess引用点阵public static OneChess[][] chessArmy = new OneChess[9][9]; //-----初始化public DC(int w, int h) {this.setBounds(300, 300, 2 * w, h);this.setTitle("◇独立钻石◇eggno8");this.getContentPane().setLayout(gamepanellayer);this.getContentPane().add(this.leftpanel);this.leftpanel.setLayout(this.optionlayer);this.leftpanel.add(jl1);this.leftpanel.add(jl2);this.getContentPane().add(this.rightpanel);this.rightpanel.setLayout(chessboardlayer);for (int row = 0; row < 9; row++) {for (int col = 0; col < 9; col++) {boolean flag = chessdot[col][row];OneChess oc = new OneChess(flag, col, row);if (!chessboard[col][row]) {oc.setBoard();}this.chessArmy[col][row] = oc;this.rightpanel.add(oc);}}this.setVisible(true);}public static boolean canMove() {boolean f = false;if (oldx == newx && (oldy == newy + 2 || newy == oldy + 2)) { if (chessArmy[oldx][ (newy + oldy) / 2].getLife()) {f = true;} else {f = false;}}if (oldy == newy && (oldx == newx + 2 || newx == oldx + 2)) { if (chessArmy[ (newx + oldx) / 2][oldy].getLife()) {f = true;} else {f = false;}}return f;}public static void doMove() {if (oldx == newx) {chessArmy[oldx][ (newy + oldy) / 2].setLife(false);if (oldy == newy) {chessArmy[ (newx + oldx) / 2][oldy].setLife(false);}chessArmy[oldx][oldy].setLife(false);chessArmy[newx][newy].setLife(true);}public static void main(String[] _s) {DC dc = new DC(360, 360);}}class OneChess extends JButton implements MouseListener { private boolean life;private boolean isout;public int xp;public int yp;public OneChess(boolean sl, int x, int y) {setLife(sl);xp = x;yp = y;this.addMouseListener(this);}public void setLife(boolean l) {life = l;if (l) {setBackground(Color.YELLOW);} else {setBackground(Color.GRAY);}}public void setMoving() {this.setBackground(Color.orange);}public void setBoard() {isout = true;setBackground(Color.WHITE);}public boolean getLife() {return life;}public void mouseClicked(MouseEvent e) {}public void mousePressed(MouseEvent e) {if (isout) {return;//-----movingflag判断moving的两个边沿if (!DC.movingflag) { //选中单个子if (DC.chessboard[xp][yp] && getLife()) {DC.oldx = xp;DC.oldy = yp;DC.movingflag = true;setMoving();}} else { //成功移动1个子if (xp == DC.oldx && yp == DC.oldy) { //放弃1个子,计数1步setLife(true);DC.movingflag = false;DC.steps++;DC.jl2.setText("当前步数:0" + DC.steps);} else if (DC.chessboard[xp][yp] && getLife()) { //点到其他子身上,切换选中的子DC.chessArmy[DC.oldx][DC.oldy].setLife(true);DC.oldx = xp;DC.oldy = yp;DC.steps++;DC.jl2.setText("当前步数:0" + DC.steps);setMoving();}if (DC.chessboard[xp][yp] && !getLife()) {DC.newx = xp;DC.newy = yp;if (DC.canMove()) {DC.doMove();DC.restcount--;DC.jl1.setText("剩余子数" + DC.restcount);DC.oldx = xp;DC.oldy = yp;setMoving();}}}return;}public void mouseReleased(MouseEvent e) {}public void mouseEntered(MouseEvent e) {}public void mouseExited(MouseEvent e) {}//actionPerformed()}。
算法课设实验报告(3篇)
第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。
为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。
二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。
1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。
(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。
- 对每种算法进行时间复杂度和空间复杂度的分析。
- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。
(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。
- 编写三种排序算法的代码。
- 分析代码的时间复杂度和空间复杂度。
- 编写测试程序,生成随机测试数据,测试三种算法的性能。
- 比较三种算法的运行时间和内存占用。
2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。
(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。
- 分析贪心算法的正确性,并证明其最优性。
(3)实验步骤:- 分析活动选择问题的贪心策略。
- 编写贪心算法的代码。
- 分析贪心算法的正确性,并证明其最优性。
- 编写测试程序,验证贪心算法的正确性。
3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。
(2)实验内容:- 实现一个动态规划算法问题,如背包问题。
- 分析动态规划算法的正确性,并证明其最优性。
(3)实验步骤:- 分析背包问题的动态规划策略。
- 编写动态规划算法的代码。
- 分析动态规划算法的正确性,并证明其最优性。
- 编写测试程序,验证动态规划算法的正确性。
三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。
算法分析与设计实验报告
算法分析与设计实验报告算法分析与设计实验报告一、引言算法是计算机科学的核心,它们是解决问题的有效工具。
算法分析与设计是计算机科学中的重要课题,通过对算法的分析与设计,我们可以优化计算机程序的效率,提高计算机系统的性能。
本实验报告旨在介绍算法分析与设计的基本概念和方法,并通过实验验证这些方法的有效性。
二、算法分析算法分析是评估算法性能的过程。
在实际应用中,我们常常需要比较不同算法的效率和资源消耗,以选择最适合的算法。
常用的算法分析方法包括时间复杂度和空间复杂度。
1. 时间复杂度时间复杂度衡量了算法执行所需的时间。
通常用大O表示法表示时间复杂度,表示算法的最坏情况下的运行时间。
常见的时间复杂度有O(1)、O(log n)、O(n)、O(n log n)和O(n^2)等。
其中,O(1)表示常数时间复杂度,O(log n)表示对数时间复杂度,O(n)表示线性时间复杂度,O(n log n)表示线性对数时间复杂度,O(n^2)表示平方时间复杂度。
2. 空间复杂度空间复杂度衡量了算法执行所需的存储空间。
通常用大O表示法表示空间复杂度,表示算法所需的额外存储空间。
常见的空间复杂度有O(1)、O(n)和O(n^2)等。
其中,O(1)表示常数空间复杂度,O(n)表示线性空间复杂度,O(n^2)表示平方空间复杂度。
三、算法设计算法设计是构思和实现算法的过程。
好的算法设计能够提高算法的效率和可靠性。
常用的算法设计方法包括贪心算法、动态规划、分治法和回溯法等。
1. 贪心算法贪心算法是一种简单而高效的算法设计方法。
它通过每一步选择局部最优解,最终得到全局最优解。
贪心算法的时间复杂度通常较低,但不能保证得到最优解。
2. 动态规划动态规划是一种将问题分解为子问题并以自底向上的方式求解的算法设计方法。
它通过保存子问题的解,避免重复计算,提高算法的效率。
动态规划适用于具有重叠子问题和最优子结构的问题。
3. 分治法分治法是一种将问题分解为更小规模的子问题并以递归的方式求解的算法设计方法。
《算法设计与分析》课程实验报告 (贪心算法(一))
《算法设计与分析》课程实验报告实验序号:07实验项目名称:实验8 贪心算法(一)一、实验题目1.删数问题问题描述:键盘输入一个高精度的正整数N(不超过250 位),去掉其中任意k个数字后剩下的数字按原左右次序将组成一个新的非负整数。
编程对给定的N 和k,寻找一种方案使得剩下的数字组成的新数最小。
若输出前有0则舍去2.区间覆盖问题问题描述:设x1,x2,...xn是实轴上的n个点。
用固定长度为k的闭区间覆盖n个点,至少需要多少个这样的固定长度的闭区间?请你设计一个有效的算法解决此问题。
3.会场安排问题问题描述:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。
设计一个有效的贪心算法进行安排。
(这个问题实际上是著名的图着色问题。
若将每一个活动作为图的一个顶点,不相容活动间用边相连。
使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。
)4.导弹拦截问题问题描述:某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。
但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。
某天,雷达捕捉到敌国的导弹来袭。
由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
给定导弹依次飞来的高度(雷达给出的高度数据是≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
二、实验目的(1)通过实现算法,进一步体会具体问题中的贪心选择性质,从而加强对贪心算法找最优解步骤的理解。
(2)掌握通过迭代求最优的程序实现技巧。
(3)体会将具体问题的原始数据预处理后(特别是以某种次序排序后),常能用贪心求最优解的解决问题方法。
三、实验要求(1)写出题1的最优子结构性质、贪心选择性质及相应的子问题。
(2)给出题1的贪心选择性质的证明。
(3)(选做题):写出你的算法的贪心选择性质及相应的子问题,并描述算法思想。
算法分析与设计-课程设计报告
XXXX大学算法设计与分析课程设计报告院 (系):年 级:姓 名: 专 业: 计算机科学与技术研究方向: 互联网与网络技术 指导教师:X X X X 大 学目 录题目1 电梯调度 (1)11.1 题目描述 ..................................................................................11.2 算法文字描述 ..............................................................................1.3 算法程序流程 ..............................................................................481.4 算法的程序实现代码 ........................................................................题目2 切割木材 .. (10)2.1题目描述 ..................................................................................10102.2算法文字描述 ..............................................................................112.3算法程序流程 ..............................................................................2.4算法的程序实现代码 ........................................................................15题目3 设计题 (17)173.1题目描述 ..................................................................................173.2 输入要求 ..................................................................................173.3输出要求 ..................................................................................173.4样例输入 ..................................................................................173.5样例输出 ..................................................................................173.6测试样例输入 ..............................................................................183.7测试样例输出 ..............................................................................183.8算法实现的文字描述 ........................................................................193.9算法程序流程 ..............................................................................3.10算法的程序实现代码 .......................................................................20算法分析与设计课程总结 (23)参考文献 (24)题目1 电梯调度1.1 题目描述一栋高达31层的写字楼只有一部电梯,其中电梯每走一层需花费4秒,并且在每一层楼停靠的时间为10秒,乘客上下一楼需要20秒,在此求解最后一位乘客到达目的楼层的最短时间以及具体的停靠计划。
算法设计与分析报告报告材料实验二
实验二:分治法实验一、实验目的(1)掌握设计有效算法的分治策略。
(2)通过快速排序学习分治策略设计技巧二、实验要求(1)熟练掌握分治法的基本思想及其应用实现。
(2)理解所给出的算法,并对其加以改进。
三、分治法的介绍任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。
问题的规模越小,越容易直接求解,解题所需的计算时间也越少。
而当n较大时,问题就不那么容易处理了。
要想直接解决一个规模较大的问题,有时是相当困难的。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。
由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。
在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。
这自然导致递归过程的产生。
分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
分治法的适用条件:(1)该问题的规模缩小到一定的程度就可以容易地解决;(2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
(3)利用该问题分解出的子问题的解可以合并为该问题的解;(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑贪心法或动态规划法。
第四条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
算法设计与分析实验报告
算法设计与分析报告学生姓名学号专业班级指导教师完成时间目录一、课程内容 (3)二、算法分析 (3)1、分治法 (3)(1)分治法核心思想 (3)(2)MaxMin算法分析 (3)2、动态规划 (4)(1)动态规划核心思想 (4)(2)矩阵连乘算法分析 (5)3、贪心法 (5)(1)贪心法核心思想 (5)(2)背包问题算法分析 (6)(3)装载问题算法分析 (7)4、回溯法 (7)(1)回溯法核心思想 (7)(2)N皇后问题非递归算法分析 (7)(3)N皇后问题递归算法分析 (8)三、例子说明 (9)1、MaxMin问题 (9)2、矩阵连乘 (10)3、背包问题 (10)4、最优装载 (10)5、N皇后问题(非递归) (11)6、N皇后问题(递归) (11)四、心得体会 (12)五、算法对应的例子代码 (12)1、求最大值最小值 (12)2、矩阵连乘问题 (13)3、背包问题 (15)4、装载问题 (17)5、N皇后问题(非递归) (19)6、N皇后问题(递归) (20)一、课程内容1、分治法,求最大值最小值,maxmin算法;2、动态规划,矩阵连乘,求最少连乘次数;3、贪心法,1)背包问题,2)装载问题;4、回溯法,N皇后问题的循环结构算法和递归结构算法。
二、算法分析1、分治法(1)分治法核心思想当要求解一个输入规模为n,且n的取值相当大的问题时,直接求解往往是非常困难的。
如果问题可以将n个输入分成k个不同子集合,得到k个不同的可独立求解的子问题,其中1<k≤n, 而且子问题与原问题性质相同,原问题的解可由这些子问题的解合并得出。
那末,这类问题可以用分治法求解。
分治法的核心技术1)子问题的划分技术.2)递归技术。
反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出不用进一步细分就可求解的子问题。
3)合并技术.(2)MaxMin算法分析问题:在含有n个不同元素的集合中同时找出它的最大和最小元素。
算法设计与分析课程设计报告
课程设计报告课程设计名称: 算法设计与分析系: 三系学生姓名:吴阳班级:12软件(2)班学号:20120311232成绩:指导教师:秦川开课时间:2014 学年一学期一、问题描述1.普通背包问题给定n种物品和一个背包。
物品i的重量是Wi,其价值为Vi,背包的容量为C。
选择装入的背包的物品,使得装入背包中的物品的总价值最大,在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。
2.0/1背包问题给定n种物品和一个背包。
物品i的重量是Wi,其价值为Vi,背包的容量为C。
选择装入的背包的物品,使得装入背包中的物品的总价值最大,在选择物品i 装入背包时,对于每种物品i只有两种选择,即装入背包或者不装入背包,不能将物品装入背包多次,也不能只装入部分的物品i。
3.棋盘覆盖问题在一个2k x 2k个方格组成的棋盘中恰有一个方格与其他的不同称为特殊方格,想要求利用四种L型骨牌(每个骨牌可覆盖三个方格)不相互重叠覆盖的将除了特殊方格外的其他方格覆盖。
二、问题分析1.普通背包问题对于背包问题,若它的一个最优解包含物品j,则从该最优解中拿出所含的物品j的那部分重量W,剩余的将是n-1个原重物品1,2,······,j-1,j+1,·····,n以及重为Wi-W的物品j中可装入容量为C-W的背包且具有最大价值的物品。
2.0/1背包问题如果当前背包中的物品的总容量是cw,前面的k—1件物品都已经决定好是否要放入包中,那么第k件物品是否放入包中取决于不等式cw + wk 〈= M (其中,wk为第k件物品的容量,M为背包的容量)(此即约束条件)然后我们再寻找限界函数,这个问题比较麻烦,我们可以回忆一下背包问题的贪心算法,即物品按照 物品的价值/物品的体积 来从大到小排列,然后最优解为(1,1,1.。
算法分析与设计课程实验报告
算法分析与设计课程实验报告班级: 131213学号: 13121XXX姓名: XXX指导老师:邓凡目录算法分析与设计课程实验报告 (1)实验一排序 (1)1. 课本练习2.3-7 (1)2. 实现优先队列 (2)3.快速排序 (2)4. 第k大元素 (3)实验二动态规划 (4)1. 矩阵链乘 (4)2. 最长公共子序列 (5)3. 最长公共子串 (7)4. 最大和 (9)5. 最短路径 (10)实验三贪心策略 (11)1. 背包问题 (11)2. 任务调度 (14)3. 单源点最短路径 (15)4. 任意两点间最短路径 (16)实验四回溯法 (18)1. 0-1背包问题 (18)2. 8-Queen问题 (21)实验一排序1.课本练习2.3-7(1)问题描述描述一个运行时间为 (nlgn)的算法,给定n个整数的集合S和另一个整数x,该算法能确定S中是否存在两个其和刚好是x的元素。
(2)问题分析该问题首先要进行排序,然后用二分查找法判断S中是否存在两个其和刚好是x的元素,因为时间复杂度为(nlgn),所以可以采用归并排序。
(3)算法分析归并排序的思想是将n个元素分成各含n/2个元素的子序列,然后对两个子序列递归地进行排序,最后合并两个已排序的子序列得到排序结果。
二分查找的思想是对于集合中的每一个数字,用二分法找到x-S[i]的位置,若存在且不为其本身,则输出S中存在有两个和等于x的元素;否则,不存在。
(4)实验结果2.实现优先队列(1)问题描述实现优先队列,维护一组元素构成的集合S。
(2)问题分析优先队列是基于堆排序的。
首先将集合S中的元素进行堆排序。
当进行操作时,要不断维护集合S的有序性,即要不断地调整堆。
(3)算法分析本程序中主要的函数有INSERT():需要调用INCREASE_KEY()来维护堆,其时间复杂度为O(lgn),函数MAXIMUM()仅需要返回S[1],时间复杂度为 (1),函数EXTRACT_MAX()需要调用堆排序中的MAX_HEAPIFY,时间复杂度为O(lgn),函数INCREASE_KEY()更新结点到根结点的路径长度为O(lgn),时间复杂度为O(lgn)。
算法分析与设计课程设计报告
算法分析与设计课程设计报告目录一、问题描述 (1)1、普通背包问题 (1)2、0-1背包问题 (1)3、棋盘覆盖问题 (1)二、问题分析 (2)1、普通背包问题 (2)2、0-1背包问题 (2)3、棋盘覆盖问题 (3)三、算法设计 (3)1、普通背包问题 (3)2、0-1背包问题 (4)3、棋盘覆盖问题 (4)四、算法实现 (6)1、普通背包问题 (6)2、0-1背包问题 (8)3、棋盘覆盖问题 (10)五、测试分析 (11)1、普通背包问题 (11)2、0-1背包问题 (13)3、棋盘覆盖问题 (15)六、结论 (16)七、源程序 (17)1、普通背包问题 (17)2、0-1背包问题 (20)3、棋盘覆盖问题 (24)八、参考文献 (26)一、问题描述1、普通背包问题有一个背包容量为C,输入N个物品,每个物品有重量S[i],以及物品放入背包中所得的收益P[i]。
求选择放入的物品,不超过背包的容量,且得到的收益最好。
物品可以拆分,利用贪心算法解决。
2、0-1背包问题在0/1背包问题中,需对容量为c的背包进行装载。
从n个物品中选取装入背包的物品,每件物品i的重量为wi, 价值为pi。
对于可行的背包装载,背包中的物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即取得最大值。
约束条件 <=c和。
在这个表达式中,需求出xi的值。
xi=1表示物品i装入背包中,xi=0表示物品i不装入背包。
3、棋盘覆盖问题在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。
在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
∑=niii xw1[]()nixi≤≤∈11,0∑=niii xp1二、问题分析1、普通背包问题贪心算法的基本思想是:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的求得更好的解。
算法设计与分析课程设计报告
算法与分析课程设计报告题目:算法设计和分析专业:网络工程班级:1020552学号:11姓名:赫前进太原工业学院计算机工程系2012年11月24 日第二章主元素问题一、算法问题描述主元素问题: 设T[0..n-1]是n个元素的数组。
对任一元素x,设S(x)={i|T[i]=x}。
当|S(x)|>n/2时,称x为T的主元素。
如果T中元素存在序关系,按分治策略设计并实现一个线性时间算法,确定T[0..n-1]是否有一个主元素。
二、算法问题形式化表示若T 中存在主元素,则将T 分为两部分后,T 的主元素也必为两部分中至少一部分的主元素,因此可用分治法。
将元素划分为两部分,递归地检查两部分有无主元素。
算法如下:若T 只含一个元素,则此元素就是主元素,返回此数。
将T 分为两部分T1 和T2(二者元素个数相等或只差一个),分别递归调用此方法求其主元素m1 和m2。
若m1 和m2 都存在且相等,则这个数就是T 的主元素,返回此数。
若m1 和m2 都存在且不等,则分别检查这两个数是否为T 的主元素,若有则返回此数,若无则返回空值。
若m1 和m2 只有一个存在,则检查这个数是否为T 的主元素,若是则返回此数,若否就返回空值。
若m1 和m2 都不存在,则T 无主元素,返回空值。
三、期望输入与输出输入:数组中元素的个数9数组元素0 0 1 1 0 8 1 1 1输出:显示主元素是1。
四、算法分析与步骤描述选择一个元素作为划分起点,然后用快速排序的方法将小于它的移动到左边,大于它的移动到右边。
这样就将元素划分为两个部分。
此时,划分元素所在位置为k。
如果k>n/2,那么继续用同样的方法在左边部分找;如果k<n/2就在右边部分找;k=n/2就找到了中位元素。
根据快速排序的思想,可以在平均时间复杂度为O(n)的时间内找出一个数列的中位数。
然后再用O(n)的时间检查它是否是主元素。
五、问题实例及算法运算步骤首先运行程序,按照提示输入数据;其次求出在数组T[0:n]中出现次数最多的元素x出现的次数k;然后用select方法线性时间选择,找到第(n+1)/2大的数;用QuickSort进行快速排序;用Partition方法进行数组划分,用swap将小于x的元素移到x左边,大于x的元素移到x右边;然后就可以得到时候存在主元素,输出到屏幕上。
算法分析与设计实验报告
算法分析与设计实验报告1. 引言算法是计算机科学中的核心概念之一,它为解决问题提供了一种清晰、有效的方法。
本实验报告旨在通过分析与设计一个特定算法的实验过程,来加深对算法的理解和应用。
2. 实验背景在现代社会中,算法的应用无处不在。
无论是搜索引擎的排序算法,还是社交媒体的推荐算法,都离不开算法的支持。
因此,学习算法的分析与设计,对于计算机科学相关领域的学生来说具有重要的意义。
3. 实验目的本实验的主要目的是通过分析与设计一个特定算法,加深对算法的理解和应用。
通过实际操作,学生将能够熟悉算法的设计过程,并能够分析算法的效率和复杂性。
4. 实验步骤4.1 确定算法目标在开始实验之前,我们需要明确算法的目标。
在本实验中,我们将设计一个排序算法,用于对一组数字进行排序。
4.2 了解算法原理在设计算法之前,我们需要对目标算法的原理进行深入了解。
在本实验中,我们将选择经典的冒泡排序算法作为实现对象。
冒泡排序算法的基本思想是通过比较相邻的元素,并根据需要交换位置,使得每一轮循环都能使最大(或最小)的元素“冒泡”到数组的末尾。
通过多次迭代,最终实现整个数组的排序。
4.3 实现算法在了解算法原理后,我们将根据算法的步骤逐步实现。
具体步骤如下:1.遍历待排序数组,从第一个元素开始。
2.比较当前元素与下一个元素的大小。
3.如果当前元素大于下一个元素,则交换它们的位置。
4.继续比较下一个元素,直到遍历完整个数组。
5.重复上述步骤,直到没有需要交换的元素。
4.4 测试算法在实现算法之后,我们需要对其进行测试,以验证其正确性和效率。
我们可以准备一组随机的数字作为输入,并对算法进行测试。
通过比较输入和输出结果,我们可以判断算法是否正确。
同时,我们还可以通过计算算法的时间复杂性和空间复杂性来评估其效率。
在本实验中,我们将使用时间复杂性分析来评估算法的效率。
4.5 分析与总结通过测试和分析,我们将得出算法的执行时间和空间复杂性。
《算法设计与分析》课程实验报告 (算法问题求解基础1)
}
int s2[10] = {0,9,189,2889,38889,488889,5888889,68888889,788888889};
int a;
scanf("%d",&a);
int count;
count = 0;
while(a > 0){
题目二:最大间隙
源码:
#include<iostream>
#include<cstdio>
using namespace std;
double a[10000] = {0};
int main(){
int n;
cin>>n;
for(int i = 0 ; i < n ; i++){
cin>>a[i];
样例输出:
3.2
二、实验目的
(1)理解算法的概念
(2)理解函数渐近态的概念和表示方法
(3)初步掌握算法时间复杂度的计算方法
三、实验要求
(1)对于每个题目提交实验代码。
(2)根据程序设计测试数据,并记录测试结果,要求边界情况必须测试
(3)使用我们学过的分析方法分析你的算法的时间效率,如果可能,请进行算法的优化,尽量减小算法的时间效率或空间效率。
《算法设计与分析》课程实验报告
实验序号:1 实验项目名称:算法问题求解基础
一、实验题目
题目一:统计数字问题
题目描述
一本书的页码从自然数1开始顺序编码直到自然数n。输的页码按照通常的习惯编排,每个页码都不含有多余的前导数字0.例如,第6页用数字6表示,而不是06或者006等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2...8,9。
算法分析教(学)案设计实验报告
!
****
{
·
院系:计算机科学学院
专业:计算机科学与技术
年级:
课程名称:算法设计与分析基础
班号:
组号:
[
指导教师:
年月日
@
else
FakeCoin_1(coin,n,l,l+ps-1);
}
}
[
void FakeCoin()
{
int i=1,n, coin[100];
printf("请输入硬币的个数: ");
scanf("%d",&n);
printf("请输入硬币的重量:\n");
for(i=1;i<=n;i++)
{
{
scanf("%d",&coin[i]);
}
FakeCoin_1(coin,n,1,n);
}
实
验
结
¥
果
及
分
析通过这个实验,理解并掌握了减治法的设计思想并理解了它与分治法的区别。
在写这个算法前,一定要建立正确的求解模型。
实
验
)
结
果
及
分
析
经过这次实验,理解了变治法的设计思想,同时还掌握了堆的概念以及如何用变治法把任意给定的一组数据改变成堆。
算法分析与设计课程设计报告
目录1、课程设计的目的 (2)2、课程设计的技术要求 (2)3、题目分析 (2)4、算法分析与设计 (3)4.1游戏运行活动图 (3)4.2具体算法与程序流程分析 (3)5、方法定义及调用关系 (4)5.1方法定义: (4)5.2方法调用关系: (4)6、游戏细节设计 (4)6.1攻击招式统计: (4)6.2受到攻击后响应动作统计: (4)7、界面设计 (5)8、部分程序分析 (6)8.1 游戏初始化方法 (6)8.2 启动游戏线程方法 (6)8.3 获取两位挑战者属性的方法 (7)8.4 游戏结果返回方法 (7)8.5 游戏循环方法说明方法 (8)8.6 攻击方法说明方法 (9)8.7 防守方法 (11)8.8 休眠动作方法 (14)8.9 动作表现方法 (14)8.10游戏的循环逻辑方法 (15)9、运行结果显示与分析 (16)9.1运行结果 (16)9.2运行结果分析 (18)10、实验总结 (18)11、参考文献 (18)附录 (19)MainGame.java (19)InputFun.java (20)GameWorld.java (21)Role.java (28)Test.java (32)姓名挑战游戏1、课程设计的目的学习算法的最终目的是解决实际的应用问题,特别是非数值计算类型的应用问题。
课程设计要求同学独立完成一个较为完整的应用需求分析,在完成设计和编程大型作业的过程中,深化对算法课程中基本概念、理论和方法的理解;训练综合运用所学知识处理实际问题的能力,强化面向对象的程序设计理念;使同学的程序设计与调试水平有一个明显的提高。
经过查找参考资料、技术手册和撰写文档的实践,进一步培养软件工程师的综合素质。
2、课程设计的技术要求同学在处理每一个题目的时候,要从分析题目的需求入手,按设计抽象数据类型、构思算法、通过类的设计实现抽象数据类型、编制上机程序代码并调试的步骤完成题目,最终写出完整的分析报告。
算法分析与设计课程设计报告
算法分析与设计课程设计报告目录一、问题描述 (1)1、普通背包问题 (1)2、0-1背包问题 (1)3、棋盘覆盖问题 (1)二、问题分析 (2)1、普通背包问题 (2)2、0-1背包问题 (2)3、棋盘覆盖问题 (3)三、算法设计 (3)1、普通背包问题 (3)2、0-1背包问题 (4)3、棋盘覆盖问题 (4)四、算法实现 (6)1、普通背包问题 (6)2、0-1背包问题 (8)3、棋盘覆盖问题 (10)五、测试分析 (11)1、普通背包问题 (11)2、0-1背包问题 (13)3、棋盘覆盖问题 (15)六、结论 (16)七、源程序 (17)1、普通背包问题 (17)2、0-1背包问题 (20)3、棋盘覆盖问题 (24)八、参考文献 (26)一、问题描述1、普通背包问题有一个背包容量为C,输入N个物品,每个物品有重量S[i],以及物品放入背包中所得的收益P[i]。
求选择放入的物品,不超过背包的容量,且得到的收益最好。
物品可以拆分,利用贪心算法解决。
2、0-1背包问题在0/1背包问题中,需对容量为c的背包进行装载。
从n个物品中选取装入背包的物品,每件物品i的重量为wi, 价值为pi。
对于可行的背包装载,背包中的物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即取得最大值。
约束条件 <=c和。
在这个表达式中,需求出xi的值。
xi=1表示物品i装入背包中,xi=0表示物品i不装入背包。
3、棋盘覆盖问题在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。
在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
∑=niii xw1[]()nixi≤≤∈11,0∑=niii xp1二、问题分析1、普通背包问题贪心算法的基本思想是:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的求得更好的解。
《算法设计与分析》课程实验报告 (分治法(三))
《算法设计与分析》课程实验报告实验序号:04实验项目名称:实验4 分治法(三)一、实验题目1.邮局选址问题问题描述:在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。
用x 坐标表示东西向,用y坐标表示南北向。
各居民点的位置可以由坐标(x,y)表示。
街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。
居民们希望在城市中选择建立邮局的最佳位置,使n个居民点到邮局的距离总和最小。
编程任务:给定n 个居民点的位置,编程计算邮局的最佳位置。
2.最大子数组问题问题描述:对给定数组A,寻找A的和最大的非空连续子数组。
3.寻找近似中值问题描述:设A是n个数的序列,如果A中的元素x满足以下条件:小于x的数的个数≥n/4,且大于x的数的个数≥n/4 ,则称x为A的近似中值。
设计算法求出A的一个近似中值。
如果A中不存在近似中值,输出false,否则输出找到的一个近似中值4.循环赛日程表问题描述:设有n=2^k个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表:每个选手必须与其他n-1个选手各赛一次,每个选手一天只能赛一次,循环赛一共进行n-1天。
二、实验目的(1)进一步理解分治法解决问题的思想及步骤(2)体会分治法解决问题时递归及迭代两种不同程序实现的应用情况之差异(3)熟练掌握分治法的自底向上填表实现(4)将分治法灵活于具体实际问题的解决过程中,重点体会大问题如何分解为子问题及每一个大问题涉及哪些子问题及子问题的表示。
三、实验要求(1)写清算法的设计思想。
(2)用递归或者迭代方法实现你的算法,并分析两种实现的优缺点。
(3)根据你的数据结构设计测试数据,并记录实验结果。
(4)请给出你所设计算法的时间复杂度的分析,如果是递归算法,请写清楚算法执行时间的递推式。
四、实验过程(算法设计思想、源码)1.邮局选址问题(1)算法设计思想根据题目要求,街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。
算法设计与分析实验报告资料
算法设计与分析实验报告学院:信息学院专业:物联网1101姓名:黄振亮学号:20113379 2013年11月目录作业1 0-1背包问题的动态规划算法 (7)1.1算法应用背景 (3)1.2算法原理 (3)1.3算法描述 (4)1.4程序实现及程序截图 (4)1.4.1程序源码 (4)1.4.2程序截图 (5)1.5学习或程序调试心得 (6)作业2 0-1背包问题的回溯算法 (7)2.1算法应用背景 (3)2.2算法原理 (3)2.3算法描述 (4)2.4程序实现及程序截图 (4)2.4.1程序源码 (4)2.4.2程序截图 (5)2.5学习或程序调试心得 (6)作业3循环赛日程表的分治算法 (7)3.1算法应用背景 (3)3.2算法原理 (3)3.3算法描述 (4)3.4程序实现及程序截图 (4)13.4.1程序源码 (4)3.4.2程序截图 (5)3.5学习或程序调试心得 (6)作业4活动安排的贪心算法 (7)4.1算法应用背景 (3)4.2算法原理 (3)4.3算法描述 (4)4.4程序实现及程序截图 (4)4.4.1程序源码 (4)4.4.2程序截图 (5)4.5学习或程序调试心得 (6)2背包问题的动态规划算法作业1 0-1算法应用背景1.1该问题一直是算法与复杂,从计算复杂性来看,背包问题是一个NP难解问题。
半个世纪以来背包问题在信息加密、预算控制、项目选择、材料切割、货物装,性研究的热点之一。
另外如果能够解决这个问题那么则具有很高的经济网络信息安全等应用中具有重要的价值。
载、本文从动态规划角度给出一种解决背包在上述领域可以获得最大的价值。
价值和决策价值,问题的算法。
1.2算法原理1.2.1、问题描述:给定n种物品和一背包。
物品i的重量是wi,其价值为vi,背包的容量为C。
问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大?形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量(x1,x2,…,xn,), xi∈{0,1}, ?∑ wi xi≤c,且∑ vi xi达最大.即一个特殊的整数规划问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
XXXX大学算法设计与分析课程设计报告院(系):年级:姓名:专业:计算机科学与技术研究方向:互联网与网络技术指导教师:X X X X 大学目录题目1 电梯调度 (1)1.1 题目描述 (1)1.2 算法文字描述 (1)1.3 算法程序流程 (4)1.4 算法的程序实现代码 (8)题目2 切割木材 (10)2.1题目描述 (10)2.2算法文字描述 (10)2.3算法程序流程 (11)2.4算法的程序实现代码 (15)题目3 设计题 (17)3.1题目描述 (17)3.2 输入要求 (17)3.3输出要求 (17)3.4样例输入 (17)3.5样例输出 (17)3.6测试样例输入 (17)3.7测试样例输出 (18)3.8算法实现的文字描述 (18)3.9算法程序流程 (19)3.10算法的程序实现代码 (20)算法分析与设计课程总结 (23)参考文献 (24)题目1 电梯调度1.1 题目描述一栋高达31层的写字楼只有一部电梯,其中电梯每走一层需花费4秒,并且在每一层楼停靠的时间为10秒,乘客上下一楼需要20秒,在此求解最后一位乘客到达目的楼层的最短时间以及具体的停靠计划。
例如:此刻电梯停靠需求为4 5 10(有三位乘客,他们分别想去4楼、5楼和10楼),如果在每一层楼都停靠则三位乘客到达办公室所需要的时间为3*4=12秒、4*4+10=26秒、4*9+2*10=56秒,则最后一位乘客到达办公室的时间为56秒,相应的停靠计划为4 5 10均停靠。
对于此测试用例电梯停靠计划方案:4 10,这样到第4楼的乘客所需时间为3*4=12秒,到第5楼的乘客所需时间为3*4+20=32秒,到第10楼的乘客所需时间为9*4+10=46秒,即最后到达目的楼层的顾客所需时间为46秒。
输入要求:输入的第1行为整数n f1 f2 … fn,其中n表示有n层楼需要停靠,n=0表示没有更多的测试用例,程序终止运行。
f1 f2 … fn表示需要停靠的楼层(n<=30,2<=f1<f2…fn<=31),每一个数字都用一个空格隔开。
输出要求:对于每一个测试用例,第1行输出最后一位乘客到达目的楼层所需时间,第2行输出停靠次数和相应的停靠方案,每一个数字用一个空格隔开。
1.2 算法文字描述程序实现的算法思想,将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到远问题的解。
与分治法不同的是,适合用动态规划发求解的子问题往往不是相互独立。
若用分治法求解这类问题,则分解的子问题数目太多,以至于最后解决原问题需要耗费指数时间。
然而,不同子问题的数目常常是多项式量级。
在分治法求解时,有些子问题被重复计算了许多次。
如果能够保存已解决的子问题的答案,而在需要时在找出以求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。
为了达到这个目的,可以采用一个表来记录所有已解决的子问题的答案。
不管子问题以后是否被使用,只要他被计算过,就将其结果填入表中。
动态规划算法适合求解最优化问题,设计动态规划算法的具体步骤如下:○1找出最优解的性质,并刻画其结构;○2递归地定义最优值;○3以自底向上的方式计算最优值;○4根据计算最优值时得到的信息,构造最优解。
例如:给定金额n以及1,2,5分硬币,求找n的最少硬币数。
对于大于1分的找零理所当然可以找零1分,大于2分和5分的找零与此类似,那么找零时就有三种选择,即找零后剩余金额为n-1,n-2,n-5,这三种选择总的找零数最少的方案即为所求解的方案。
显然,最终的找零方案与执行当前选择后剩余的金额的找零相关,即金额n的最优找零方案包含了金额n-1,n-2,n-5的最优找零方案,于是可得如下状态转移方程:具体的求解过程:初始化F(1)=1,F(2),F(5)=1F(1) 1F(2) 1F(3) min{F(2)+1,F(1)+1}=2F(4) min{F(2)+1,F(3)+1}=2F(5) 1F(6) min{F(1)+1,F(4)+1,F(1)+1}=2…F(n) min{F(n-1)+1,F(n-2)+1,F(n-5)+1}算法设计思路及求解过程思路:题目所描述的整个过程是“并行的”,而且所有人到达各自楼层的用时只与最晚到达的人有关。
由于去各个楼层的具体数目对结果没有影响,所以可以将“电梯还剩i个人”表述成“电梯里面的乘客还要去i个楼层”。
电梯从第1层开始向上运行,任意时刻的状态都可以由“电梯当前所处楼层”和“电梯里面都有哪些乘客确定”,初始状态为“电梯在1楼”和“所有乘客都在电梯上”。
在电梯运行的每一个阶段都需要作出相应的决策,哪些乘客乘坐电梯到目的层,哪些乘客选择爬楼梯到达目的地。
决策后,电梯里面的乘客被分成两部分:乘客留在电梯里面继续上升;乘客离开电梯走楼梯到达。
求当前状态下电梯里面的乘客所有人到达目的所需要的最短时间,只需要找到一个最优决策,使得下电梯的乘客和留在电梯中的乘客最晚到达时间越短越好,这个最短时间就是当前状态下的最优解。
如果假设决策后留在电梯里面的乘客到达各自楼层所需要的时间为T1,离开电梯的各自到达目的地所需时间为T2,则min{max(T1,T2)}就是当前状态的最优解,其中T1可以由“当前层数+1”和“决策后剩下的人”确定的状态得到;T2则为下电梯走楼梯到达目的走楼梯最多的那一位乘客所花时间。
如果去第k层的乘客选择在当前楼层下电梯,那么第1,2…k-1层的乘客也应该选择在此时下电梯(如图 1所示),这样就可以得到当前决策下的一个最优解。
为了进一步处理停靠请求,对楼层按从高到低进行排序,并以此进行编号,如此可以避免在求解过层中处理不连续的请求,如:4,5,10。
使用i,j两个参数表示电梯当前的状态,即电梯在第i层,电梯中有j位乘客。
综上所述,可得如下状态转移方程:f(i,j)表示电梯在第i层楼时,电梯中j个人都到达目的地所需要的最短时间。
具体求解过程:第一步:计算初始状态f(topFloor,1),f(topFloor,2),…,f(topFloor,n);第二步:根据状态转移方程计算f(i,j);第三步:根据计算最优值时记录的信息求解最优解。
1.3 算法程序流程图 1 解题结论图 2 Input函数流程图图 4 main函数流程图图 3 solve函数流程图图 5 calculate函数流程图图7 tLeave函数流程图图 6 tStay函数流程图1.4 算法的程序实现代码# include<iostream># include<cstring># include<algorithm>#include<cmath># include<limits>#include<vector>using namespace std;const int maxN=30,maxF=31;// 电梯上一层楼所需时间,电梯每次停靠时长,人走一层楼所需时间const int ve=4,st=10,vw=20;int n,f[maxN+1];//数据读取bool input(){cin>>n;if(n==0) return false;// 注意:f[1...n]中楼层数从高到低排列for(int i=n;i>=1;i--)cin>>f[i];return true;}int dp[maxF+1][maxN+1],nextJ[maxF+1][maxN+1];// 目前电梯在第currF层, 第L层到第R层乘客离开电梯// 函数返回这些离开电梯的乘客中最晚到达目的层所需时间int tLeave(int currF,int l,int r){if(l>r) return 0;// 仅需考虑两端, 无论此刻电梯在何处, 第l-r层花时间最多的// 一定是离电梯当前所在楼层最远的乘客return max(abs(currF-f[l]),abs(currF-f[r]))*vw;}// 现在电梯在第i层, 电梯里面本来有j位乘客, 离开电梯的乘客剩下jj位int tStay(int i,int j,int jj){// 没有乘客离开,电梯不停if(j==jj || i==1)return dp[i+1][jj] +ve;// 所有人都离开电梯else if(jj==0)return 0;// 一般情况,电梯在第i层停靠elsereturn dp[i+1][jj]+ve+st;}//void calculate(){// 边界:电梯在顶楼时所有人都必须下电梯int topFloor=f[1];for(int j=1;j<=n;j++){// 1,j表示停靠请求的编号,编号越小表示编号停靠楼层越高dp[topFloor][j]=tLeave(topFloor,1,j);}for(int i=topFloor-1;i>=1;i--){// i表示电梯此刻所在位置for(int j=1;j<=n;j++){dp[i][j]=numeric_limits<int>::max();for(int jj=0;jj<=j;jj++){// 计算离开电梯的人和留在电梯里面的人中到达目的地最晚的int tmp=max(tStay(i,j,jj),tLeave(i,jj+1,j));// 在此求解花费时间最短的乘客if(dp[i][j]>tmp) {dp[i][j]=tmp;// jj以前的乘客均离开电梯nextJ[i][j]=jj;}}}}cout<<dp[1][n]<<endl;}// 重构最优解void rebuildSolution(){vector<int> stops;int j=nextJ[1][n],topFloor=f[1];for(int i=2;i<=topFloor;i++){if(nextJ[i][j]!=j){stops.push_back(i);j=nextJ[i][j];if(j==0) break;}}cout<<stops.size();for(int i=0;i<stops.size();i++){cout<<" "<<stops[i];}cout<<endl;}void solve(){memset(dp,0,sizeof(dp));memset(nextJ,0,sizeof(nextJ)); calculate();rebuildSolution();}题目2 切割木材2.1题目描述一个木匠从木材公司买了一批木材,每块木材的长度均相同,但由于制作家具时所需的木块长度各不相同,因此需要把这些木材切割成长度不同的木块。