算法第三章上机实践报告(修订版)
7-3 最低通行费 (25 分)
问题描述
输入格式:
第一行是一个整数,表示正方形的宽度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。
算法描述
从时间来看商人只能往下或者往左走,如果将横坐标记为i,纵坐标记为j,则往下一步为(i,j+1),往右为(i+1,j)最小子问题就是min{(i,j+1),(i+1,j)},由于无法走出网格则限制条件为0<i,j<n.于是我们可以列出下图的递归方程
问题求解:⬆️为递归方程
⬇️代码实现
int f(int h,int l){
if(dp[h][l]!=0) return dp[h][l];
dp[h][l]=m[h][l];
int t = 1e9;
for(int i= 0; i < 2;i++){
int sh = h +x[i][0],sl = l + x[i][1];
if(sh >= 0 && sh < N && sl >= 0 && sl < N){
t = min(t,f(sh,sl));
}
}
if(t!=1e9){dp[h][l]=t+m[h][l];}
return dp[h][l];}
t为定义一个极大的数方便找出第一个值
心得体会:
感受到算法的威力了,从递归调用产生巨大的时间复杂度到建立备忘录再到放弃递归改成递推最后消除多余数组减少空间复杂度,算法是一门值得深究的学科
对dp的理解和体会:
真正的四两拨千斤算法,特别有意思