1.1问题描述
最低通行费
一个商人穿过一个N×N的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。
这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?
注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。
1.2算法描述
本题我利用了动态规划的算法,利用二维数组进行了数据的储存,然后分析到第一列和第一行每一个数据的更新都只能来自一个方向,因此,先进行了这两组数据的初始化更新,从第二个数据开始让前一个数据加上后一个数据等于后一个数据,初始化数组之后,我从第二行第二列的元素开始,比较这个元素的同一列上一行的数据和同一行上一列的的元素的大小,取小的元素加上这个元素等于新的数组所储存的值,利用循环,最后得出最右下角的元素为最优解。
算法的主体:
for(int i = 1;i<n;i++){
D[0][i] = D[0][i-1]+D[0][i];
D[i][0] = D[i-1][0]+D[i][0];
}//首先进行了表的初始化
for(int i = 1;i<n;i++){
for(int j = 1;j<n;j++){
if(D[i][j]+D[i][j-1]<D[i-1][j]+D[i][j]){
D[i][j] = D[i][j]+D[i][j-1];
}
else{
D[i][j] = D[i-1][j]+D[i][j];
}
}
}//比较这个元素的同一列上一行的数据和同一行上一列的的元素的大小,取小的元素加上这个元素等于新的数组所储存的值
cout<<D[n-1][n-1];//利用循环,最后得出最右下角的元素为最优解
1.3问题求解
1.3.1根据最优子结构性质,列出递归方程式
D[i][j] = min(D[i-1][j], D[i][j-1]) + D[i][j] i≥1且j≥1
D[i][j] = D[0][i-1]+D[0][i] j=1,i=0
D[i][j] = D[i-1][0]+D[i][0i] i=1,j=0
1.3.2给出填表法中表的维度、填表范围和填表顺序
此表为一个二维数组,维度为2*2.
进行了表的初始化以后,填表范围从第二行第二列开始
填表顺序从上到下,从左到右
1.3.3分析该算法的时间和空间复杂度
时间复杂度为O(n^2)
空间复杂度为O(n^2)
1.4心得体会
通过了四道题的训练,深刻体会到了动态规划其实就像是填表,填表很关键,是步骤的一步步实现,分析最优解的性质,并刻画其结构特征,递归的定义最优解,构造递归式子,以自底向上或自顶向下的方式构造问题的最优解
1.4.1本次实践收获
学会了利用动态规划来优化时间复杂度,减少时间的消耗,和搭档一起合作解决了难题,深切的体会到了动态规划算法的精髓。
1.4.2本次实践疑惑
有时候对一些临界值不是很会区分,而且有时很难应用动态规划算法来解决问题,分不清几种算法。
2、对动态规划算法的理解和体会
动态规划最重要的是掌握他的思想,动态规划的核心思想是把原问题分解成子问题进行求解,也就是分治的思想,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果。但不同的是,分治法在子问题和子子问题等上被重复计算了很多次,而动态规划则具有记忆性,通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,用动态规划解决问题的核心就在于填表,表填写完毕,最优解也就找到。
最优性原理是动态规划的基础,最优性原理是指“多阶段决策过程的最优决策序列具有这样的性质:不论初始状态和初始决策如何,对于前面决策所造成的某一状态而言,其后各阶段的决策序列必须构成最优策略”。