算法第三章上机实践报告

1.1问题描述

一个商人穿过一个N×N的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。

这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?

注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。

输入格式:

第一行是一个整数,表示正方形的宽度N (1≤N<100);

后面N行,每行N个不大于100的整数,为网格上每个小方格的费用。

输出格式:

至少需要的费用。

 

1.2算法描述

从二维数组第一个元素开始,每个元素只能上下左右移动,又因为必须在(2N-1)个单位时间穿越出去,假如网格为5*5的二维数组,即必须在2*5-1=9个单位时间穿越出去,因此从第一个元素开始,只能往右或者往下走,才有可能在(2N-1)个单位时间出去。因此,定义一个二维数组m[n][n],每个位置的元素值代表从起点到此位置的最低费用值,即为最优解。由于第一行和第一列的最优解在条件限制内只能是从该行(该列)一直往右(往下)的累加值,因此可以单独先将第一行和第一列的最低通行费求出来,从第二行第二列的位置开始进行递归方程的求解,m[n][n]的值即为本题的答案。

 

1.3问题求解

1.1.1根据最优子结构性质,列出递归方程式

除了第一行和第一列外的其他元素,到达该元素位置的前提是上一个到达的网格点位置在该元素位置的左边或上边,因此先判定该元素左边和上边的值哪个比较小,选择较小的值加上该位置所需消耗费用即为该位置的最低通行费用,即最优解。

递归方程式可列为:m[i][j]=min(m[i-1][j],m[i][j-1])+a[i][j],其中边界值为i>=2,j>=2。

1.1.2给出填表法中表的维度、填表范围和填表顺序

表的维度:二维

填表范围:i从1到n,j从1到n。其中i=1时,m[1][j]=m[1][j-1]+a[1][j],a[i][j]为每个网格点所需消耗费用的二维数组;同理,j=1时,m[i][1]=m[i-1][1]+a[i][1]。

                 i,j>=2时,按1.1.1中递归方程式填表。

填表顺序:除去第一行向右累加,第一列向下累加外,从第二行第二个元素开始,按从左到右顺序求出第二行每个元素最优解,然后在往下进行第三行的元素最优值求解,一直到第n行最后一个元素解答出来。

因此顺序是从左到右,从上到下。

1.1.3分析该算法的时间和空间复杂度

时间复杂度:O(n^2) 二重循环

空间复杂度:O(n^2) 二维数组

 

1.3心得体会

本次实验的题目充分说明动态规划的求解方法关键在于对该题递归方程式的正确写法,并要确定i,j的条件边界值,一旦确定下来,问题迎刃而解。

如最低通行费该题,可以把第一行和第一列的最优值排除在递归方程式求解范围之外,只需从i=2,j=2开始求

又如最大子段和问题,从头开始求,但在递归方程的代入中可以不断更新最优值的起始位置和结果,这些都需要灵活运用。

 

2.对动态规划算法的理解与体会

动态规划算法用历史记录来不断更新最优解。其基本思想与分治法相似,也是将求解问题分解成若干子问题并按顺序求解,因此二维数组的建立亦需要确定填表的范围与顺序才能得到正确的结果,而为减少重复计算,有些局部的计算是不必要的,所以一般二维数组的建立也只需要半个三角形的求解范围而已。而动态规划算法的核心在于递归,解决先序的子问题后再往下得到后序子问题的答案,是动态规划算法的关键点所在。

posted @ 2021-10-23 12:30  zbjzbj  阅读(64)  评论(0编辑  收藏  举报