动态规划-最低通行费

Posted mtstory

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划-最低通行费相关的知识,希望对你有一定的参考价值。

一个商人穿过一个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。

 

商人必须在(2N-1)个单位时间穿越出去

而正方形网格边长为N,商人初始位置在左上角

则商人只能往右或者往下走

 

我们可以认为商人达到某个位置时立刻交费(题目是经过,不过没影响),当商人到某一位置时,所用的最小费用为该位置的费用加上该位置的左边和上边中费用较小的一边,如果在边界(第一行或第一列)则直接取(左边或上边),不用比较

定义二维数组a[i][j]表示到位置第i行第j列,a[i][j]初始值为到达该位置时交的费用,程序执行完毕后a[i][j]为到达该位置的最小费用(从开始点到该位置的路径上所有的费用)

则一般情况:a[i][j]=a[i][j]+min(a[i-1][j],a[i][j-1])

第一行:a[i][j]=a[i][j]+a[i][j-1]

第一列:a[i][j]=a[i][j]+a[i-1][j]

 

这里我按从左往右从上往下的顺序计算,每次计算完当前行时上一行就失去作用了,因为计算完当前行后便计算下一行,而当前行的上一行与当前行的下一行之间隔了一行,每个位置的计算只需要其左边和上边,所以我只用了一维数组,每次计算都是当前行替代上一行

这里数组a是临时存储当前行的每个位置的费用,数组b是到达当前行的每个位置的最小费用

 

#in0clude<iostream>
using namespace std;
int main()
{
    int a[100],b[100],n,i,j;
    while(cin>>n)
    {
        cin>>b[0];
        for(i=1;i<n;i++)
        {
            cin>>b[i];
            b[i]+=b[i-1];
        }
        for(i=1;i<n;i++)
        {
            for(j=0;j<n;j++)
                cin>>a[j];
            b[0]+=a[0];
            for(j=1;j<n;j++)
                b[j]=a[j]+min(b[j],b[j-1]);
        }
        cout<<b[n-1]<<
;
    }
    return 0;
}

 

以上是关于动态规划-最低通行费的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode | 983.最低票价(动态规划)

LeetCode | 983.最低票价(动态规划)

第一章 动态规划未完结

动态规划解决旅行车票费用问题

算法分析第三章实验总结

最低通行费