7-3 最低交通费

  1.1 问题描述

一个商人穿过一个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 算法描述

  本题要求解商人在规定时间内走出去所用的最少花费,这个“最少花费”就代表该大问题是由很多个小问题环环相扣组成的,我们将该大问题拆开,就可以得到很多的小问题,“最少花费”就是指我们要在小问题中找到最优解。这满足了“最优子结构”的特性,且该问题分解的小问题环环相扣,这就意味着这个题目需要我们使用动态规划的方法来写。

  我觉得用“填表法”来写比较合适,因为前文说迷宫的规格是N*N,所以要创建一个N*N的表格,表格的每一个代表商人走到迷宫的同样位置所需要的最少的金钱,因为必须在2N-1的时间内走出去,所以商人只能往右走或者往下走,这样一理解,表格的最左列和最上列就可以填了,因为商人只能往下走和往右走。有了这两列的基础我们就可以将整个表格填上。

 设i代表的是表格的行,j代表的是表格的列。

 设表格为b[n][n],从b[1][1]开始计数。

 b[1][1]=1

 for(int i=2;i<=n;i++)

   b[i][1]+=  b[i-1][1];(将第一列填上)

 for(int j=2;j<=n;j++)

  b[1][j]+=b[1][j-1];(将第一行填上)

for(int i=2;i<=n;i++)

  for(int j=2;j<=n;j++)

    b[i][j]+=min(b[i-1][j],b[i][j-1]);(按行依次填表,最后的b[n][n]即为最小值)

1.3 问题求解:

 

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

mf[1][1] = a[1][1]//边界条件
mf[1][j] = mf[1][j-1] + a[1][j], j>1
mf[i][1] = mf[i-1][1] + a[i][1], i>1
mf[i][j] = max{mf[i-1][j],mf[i][j-1]}+a[i][j], i>1, j>1

  

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

表的维度为二维,填表范围为从表b[1][1]一直到b[n][n],顺序是先从第一列和第一行在按行填完整张表。

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

时间复杂度为O(n^2)

空间复杂度为O(n^2)

1.3 心得体会(对本次实践收获及疑惑进行总结)

在解决问题之前,要先看懂题目,看透题目,看题目中有无给我们隐藏的信息(比如本题的向右走和向下走),然后在思考问题。在思考问题的过程中如果碰到环环相扣的问题时,大概率就是用动态规划的方法进行解决。再写动态规划时要注意递归方程的书写,不要忘记加边界条件等等。。

 

 

  

 

posted @ 2021-10-26 23:10  堡皇泻  阅读(23)  评论(0编辑  收藏  举报