算法第三章上机实践报告
1.1 问题描述
7-3 最低通行费 (25 分)
一个商人穿过一个N×N的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。
这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?
注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。
输入格式:
第一行是一个整数,表示正方形的宽度N (1≤N<100);
后面N行,每行N个不大于100的整数,为网格上每个小方格的费用。
输出格式:
至少需要的费用。
输入样例:
5
1 4 6 8 10
2 5 7 15 17
6 8 9 18 20
10 11 12 19 21
20 23 25 29 33
输出样例:
109
样例中,最小值为109=1+2+5+7+9+12+19+21+33。
1.2 算法描述
根据题意,商人想要在规定时间内花费最少的钱通过网格,只能往下走或者往右走,不能往上或往左这样只会增加花费。当我们把商人放在[i][j]格子里的时候,他只能从[i-1][j]或[i][j-1]格子来,而到底是从哪里来的,则取决于这两条路哪个的费用更少。所以我们定义一个数组f[i][j]存放商人从起点到该位置的最低费用,也就是求它累加值的最优解。
1.3 问题求解:
①根据最优子结构性质,列出递归方程式:
当 i=1时,
f[i][j]=x+f[i][j-1];
当 j=1时,
f[i][j]=x+f[i-1][j];
否则,
f[i][j]=min(f[i][j-1],f[i-1][j])+x;
由于商人从[1][1]格子出发,所以我们应提前初始化数组:
int f[N+1][N+1]={0};
②给出填表法中表的维度、填表范围和填表顺序
维度:二维
填表范围:f[1][1]到f[N][N]
填表顺序:从左到右,从上到下
③ 分析该算法的时间和空间复杂度
时间复杂度:O(n2),是由于填表时使用了两层循环
空间复杂度:O(n2),是因为数组大小由网格大小N决定
④心得体会(对本次实践收获及疑惑进行总结)
本次实验课加深了我对动态规划的理解以及应用,首先确定边界条件正如这题商人从[1][1]出发,那么为了[0][ ]以及[ ][0]不影响计算,我们应该提前初始化数组;而在纸上根据递归方程式演算出填表顺序是从上到下从左到右的,理清思路便于做题。
2. 你对动态规划算法的理解和体会
动态规划算法主要是用来解决具有最优子结构性质和子问题重叠性质的问题,首先需要我们找出题目的边界条件,再就是写出动态规划递归方程式,通过方程式以及画图理解确定填表顺序,这样有助于我们理解题意并且更好的帮助我们做题。